@songsid/agend 2.3.0-beta.8 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -8
- package/README.zh-TW.md +16 -8
- package/dist/adapter-world.js.map +1 -1
- package/dist/agend-home.d.ts +5 -0
- package/dist/agend-home.js +7 -0
- package/dist/agend-home.js.map +1 -0
- package/dist/agent-cli-instructions.md +9 -2
- package/dist/agent-cli.js +44 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +9 -0
- package/dist/agent-endpoint.js +23 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.js +1 -1
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.d.ts +16 -0
- package/dist/agent-whats-new.js +54 -11
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/apply-job.js.map +1 -1
- package/dist/atomic-write.js.map +1 -1
- package/dist/auth-api.d.ts +12 -0
- package/dist/auth-api.js +77 -22
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +4 -0
- package/dist/authority/authority-state.js +17 -8
- package/dist/authority/authority-state.js.map +1 -1
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +16 -8
- package/dist/authority/web-authority.js +19 -5
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/antigravity.d.ts +2 -2
- package/dist/backend/antigravity.js +2 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.js +13 -4
- 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-package.d.ts +30 -0
- package/dist/backend/codex-package.js +133 -0
- package/dist/backend/codex-package.js.map +1 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.d.ts +2 -0
- package/dist/backend/codex.js +25 -5
- 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/effort-metadata.js.map +1 -1
- package/dist/backend/grok.js +58 -3
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro-engine-ledger.js.map +1 -1
- package/dist/backend/kiro-kas-store.js.map +1 -1
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +9 -1
- package/dist/backend/kiro.js +102 -1
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.js.map +1 -1
- package/dist/backend/mock.js.map +1 -1
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/opencode-permission.js +1 -1
- package/dist/backend/opencode-permission.js.map +1 -1
- package/dist/backend/opencode.js +2 -1
- package/dist/backend/opencode.js.map +1 -1
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend-availability.js.map +1 -1
- package/dist/backend-command.d.ts +2 -0
- package/dist/backend-command.js +3 -1
- package/dist/backend-command.js.map +1 -1
- package/dist/backend-outage.js.map +1 -1
- package/dist/binary-probe.js +1 -1
- package/dist/binary-probe.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +139 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +137 -0
- package/dist/bug-report.js.map +1 -0
- package/dist/bundled-skills.d.ts +18 -0
- package/dist/bundled-skills.js +38 -0
- package/dist/bundled-skills.js.map +1 -0
- package/dist/cache-service.js +1 -1
- 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 +4 -0
- package/dist/channel/adapters/discord.js +57 -12
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +6 -0
- package/dist/channel/adapters/telegram.js +54 -14
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-server.js +21 -4
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.d.ts +3 -1
- package/dist/channel/mcp-tools.js +43 -6
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/message-queue.js.map +1 -1
- package/dist/channel/sticker-download.js.map +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/child-process.d.ts +21 -0
- package/dist/child-process.js +54 -0
- package/dist/child-process.js.map +1 -0
- package/dist/classic-channel-manager.js +3 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli-entry.js.map +1 -1
- package/dist/cli-flags.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +443 -311
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +1 -1
- package/dist/command-table.js +1 -1
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.js.map +1 -1
- package/dist/completion-install.js.map +1 -1
- package/dist/completion.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +81 -8
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +15 -3
- package/dist/config.js +41 -10
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.js.map +1 -1
- package/dist/context-guardian.js.map +1 -1
- package/dist/coredump-filter.js.map +1 -1
- package/dist/cpu-profile.js.map +1 -1
- package/dist/cross-instance-envelope.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 +39 -1
- package/dist/daemon.js +234 -15
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js.map +1 -1
- package/dist/darwin-memory.js +1 -1
- package/dist/darwin-memory.js.map +1 -1
- package/dist/dashboard-live.d.ts +8 -0
- package/dist/dashboard-live.js +35 -0
- package/dist/dashboard-live.js.map +1 -0
- package/dist/dashboard-permissions.d.ts +69 -0
- package/dist/dashboard-permissions.js +138 -0
- package/dist/dashboard-permissions.js.map +1 -0
- 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-consumed-watch.js.map +1 -1
- package/dist/delivery-outbox.js +5 -0
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/delivery-reconciliation.test.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/doctor.d.ts +8 -0
- package/dist/doctor.js +52 -0
- package/dist/doctor.js.map +1 -1
- package/dist/e2e-isolation.js.map +1 -1
- package/dist/event-log.js.map +1 -1
- package/dist/export-import.js +7 -5
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-label.js.map +1 -1
- package/dist/fleet-level-config.d.ts +1 -1
- package/dist/fleet-level-config.js +2 -0
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-lock.js +3 -2
- package/dist/fleet-lock.js.map +1 -1
- package/dist/fleet-manager.d.ts +258 -15
- package/dist/fleet-manager.js +1605 -304
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +70 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/fleet-startup.d.ts +14 -0
- package/dist/fleet-startup.js +30 -0
- package/dist/fleet-startup.js.map +1 -0
- package/dist/fleet-traffic.d.ts +36 -0
- package/dist/fleet-traffic.js +100 -0
- package/dist/fleet-traffic.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +0 -20
- package/dist/forged-envelope-scan.js +3 -2
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/full-restart.d.ts +5 -5
- package/dist/full-restart.js +5 -5
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +52 -11
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +5 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +3 -1
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +8 -9
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +1 -1
- 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.canvas-worker-off.md +321 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +28 -4
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +553 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +170 -35
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/general-knowledge/steering/core-rules.md +1 -1
- package/dist/host-memory.js.map +1 -1
- package/dist/idle-gate-log.d.ts +19 -0
- package/dist/idle-gate-log.js +15 -0
- package/dist/idle-gate-log.js.map +1 -0
- package/dist/instance-config-impact.js +25 -4
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -1
- package/dist/instance-lifecycle.js +86 -25
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +12 -6
- package/dist/instructions.js +19 -10
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.js.map +1 -1
- package/dist/kiro-db-reader.js.map +1 -1
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/kiro-log-gate.js.map +1 -1
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/locale.js +428 -20
- package/dist/locale.js.map +1 -1
- package/dist/log-service.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/logger.js +3 -2
- package/dist/logger.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/login-flows.js +1 -1
- package/dist/login-manager.js.map +1 -1
- package/dist/login-shell.js +3 -1
- package/dist/login-shell.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 +83 -4
- package/dist/ls-rows.js.map +1 -1
- package/dist/memory-pressure.js.map +1 -1
- package/dist/muse-usage-relay.js.map +1 -1
- package/dist/needs-you-hub.d.ts +98 -1
- package/dist/needs-you-hub.js +313 -44
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you-live.d.ts +5 -2
- package/dist/needs-you-live.js +6 -3
- package/dist/needs-you-live.js.map +1 -1
- package/dist/needs-you.d.ts +68 -3
- package/dist/needs-you.js +38 -4
- package/dist/needs-you.js.map +1 -1
- package/dist/network-family.js.map +1 -1
- package/dist/operator-control-paths.js +3 -4
- package/dist/operator-control-paths.js.map +1 -1
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +76 -19
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +112 -64
- package/dist/outbound-schemas.js +39 -12
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/outbox-open-error.js.map +1 -1
- package/dist/pane-context-cache.js.map +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/private-dir.js.map +1 -1
- package/dist/probe-worker-pool.js.map +1 -1
- package/dist/profile-control.js.map +1 -1
- package/dist/prompt-file-ref.js.map +1 -1
- package/dist/provider-probe.js.map +1 -1
- package/dist/provider-secret-registry.d.ts +5 -3
- package/dist/provider-secret-registry.js +8 -2
- package/dist/provider-secret-registry.js.map +1 -1
- package/dist/public-link-auto-open.d.ts +32 -0
- package/dist/public-link-auto-open.js +86 -0
- package/dist/public-link-auto-open.js.map +1 -0
- package/dist/public-link-owner.d.ts +10 -0
- package/dist/public-link-owner.js +36 -0
- package/dist/public-link-owner.js.map +1 -0
- package/dist/public-link-progress.d.ts +12 -1
- package/dist/public-link-progress.js +5 -10
- package/dist/public-link-progress.js.map +1 -1
- package/dist/public-preview.js.map +1 -1
- package/dist/public-tunnel-config.d.ts +11 -0
- package/dist/public-tunnel-config.js +68 -0
- package/dist/public-tunnel-config.js.map +1 -0
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +19 -6
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +48 -3
- package/dist/public-web-link.js +177 -51
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +9 -0
- package/dist/quickstart-api.js +82 -0
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +5 -0
- package/dist/quickstart.js +40 -25
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-dedup.js.map +1 -1
- package/dist/resource-report.js +1 -1
- package/dist/resource-report.js.map +1 -1
- package/dist/restart-guard.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.js.map +1 -1
- package/dist/runtime-cpu-profile.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/scheduler.js.map +1 -1
- package/dist/scheduler/task-board-text.d.ts +26 -0
- package/dist/scheduler/task-board-text.js +140 -0
- package/dist/scheduler/task-board-text.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +730 -0
- package/dist/scheduler/task-board.js +2179 -0
- package/dist/scheduler/task-board.js.map +1 -0
- package/dist/scheduler/types.d.ts +6 -1
- package/dist/sd-notify.js +2 -1
- package/dist/sd-notify.js.map +1 -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/secret-file.js.map +1 -1
- package/dist/secret-store.d.ts +2 -0
- package/dist/secret-store.js +21 -0
- package/dist/secret-store.js.map +1 -1
- package/dist/service-installer.d.ts +75 -0
- package/dist/service-installer.js +206 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +44 -0
- package/dist/service-owner.js +48 -0
- package/dist/service-owner.js.map +1 -0
- package/dist/service-plan.d.ts +39 -2
- package/dist/service-plan.js +188 -6
- package/dist/service-plan.js.map +1 -1
- package/dist/session-oom.d.ts +21 -0
- package/dist/session-oom.js +139 -0
- package/dist/session-oom.js.map +1 -0
- package/dist/settings-api.d.ts +13 -0
- package/dist/settings-api.js +73 -12
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.d.ts +5 -0
- package/dist/settings-change.js +167 -6
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +9 -1
- package/dist/settings-confirmation.js +18 -8
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-control.js +2 -1
- package/dist/settings-control.js.map +1 -1
- package/dist/settings-effect.js +29 -4
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +13 -0
- package/dist/settings-http-confirmation.js +15 -3
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +13 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/settings-request-capability.d.ts +4 -1
- package/dist/settings-request-capability.js +11 -3
- package/dist/settings-request-capability.js.map +1 -1
- package/dist/settings-transaction.js.map +1 -1
- package/dist/setup-auth.d.ts +1 -0
- package/dist/setup-auth.js +2 -1
- package/dist/setup-auth.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/setup-host.d.ts +6 -1
- package/dist/setup-host.js +15 -4
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +6 -3
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.d.ts +5 -0
- package/dist/spawn-gate.js +28 -8
- package/dist/spawn-gate.js.map +1 -1
- package/dist/start-attempt.d.ts +1 -0
- package/dist/start-attempt.js +18 -0
- package/dist/start-attempt.js.map +1 -0
- package/dist/start-failure-notice.d.ts +4 -0
- package/dist/start-failure-notice.js +20 -0
- package/dist/start-failure-notice.js.map +1 -0
- package/dist/start-failure.d.ts +147 -0
- package/dist/start-failure.js +281 -0
- package/dist/start-failure.js.map +1 -0
- package/dist/startup-memory-deadline.d.ts +23 -0
- package/dist/startup-memory-deadline.js +55 -0
- package/dist/startup-memory-deadline.js.map +1 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/storm-window.js.map +1 -1
- package/dist/systemd-peer-bus.js.map +1 -1
- package/dist/target-queue-worker.js.map +1 -1
- package/dist/task-board-summary.d.ts +101 -0
- package/dist/task-board-summary.js +177 -0
- package/dist/task-board-summary.js.map +1 -0
- package/dist/task-board-tool.d.ts +25 -0
- package/dist/task-board-tool.js +155 -0
- package/dist/task-board-tool.js.map +1 -0
- package/dist/task-board-waker.d.ts +51 -0
- package/dist/task-board-waker.js +141 -0
- package/dist/task-board-waker.js.map +1 -0
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.js +1 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.d.ts +104 -0
- package/dist/tmux-exec-helper.js +412 -0
- package/dist/tmux-exec-helper.js.map +1 -0
- package/dist/tmux-manager.d.ts +1 -0
- package/dist/tmux-manager.js +29 -13
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +2 -2
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js +9 -42
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-archiver.js.map +1 -1
- package/dist/topic-commands.d.ts +13 -0
- package/dist/topic-commands.js +56 -33
- package/dist/topic-commands.js.map +1 -1
- package/dist/topic-link.js.map +1 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-monitor.js +5 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +2 -0
- package/dist/transcript-sources.js +4 -0
- package/dist/transcript-sources.js.map +1 -1
- package/dist/tunnel/cloudflared-install.js +3 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/cloudflared.d.ts +7 -16
- package/dist/tunnel/cloudflared.js +100 -13
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/lease.js +3 -2
- package/dist/tunnel/lease.js.map +1 -1
- package/dist/tunnel/manager.js.map +1 -1
- package/dist/tunnel/named-diagnostics.d.ts +13 -0
- package/dist/tunnel/named-diagnostics.js +52 -0
- package/dist/tunnel/named-diagnostics.js.map +1 -0
- package/dist/tunnel/public-fetch.js.map +1 -1
- package/dist/tunnel/purpose-lane.js.map +1 -1
- package/dist/tunnel/types.d.ts +4 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +55 -2
- package/dist/ui/app-effects.js +27 -5
- package/dist/ui/app.html +2 -0
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-effects.js +15 -7
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-render.js +67 -20
- package/dist/ui/chat-store.js +218 -48
- package/dist/ui/chat-strings.js +42 -10
- package/dist/ui/chat-thread.js +249 -23
- package/dist/ui/effect-trial-controller.js +13 -8
- package/dist/ui/effect-trial-offer.js +2 -31
- package/dist/ui/effects-waker.js +2 -0
- package/dist/ui/fleet-canvas-layout.js +13 -4
- package/dist/ui/fleet-canvas.js +120 -43
- package/dist/ui/fleet-office-editor.js +149 -0
- package/dist/ui/fleet-office-model.js +358 -0
- package/dist/ui/fleet-office-pack.js +199 -0
- package/dist/ui/fleet-office-skin.js +474 -0
- package/dist/ui/fleet-office-store.js +49 -0
- package/dist/ui/fleet-office-zones.js +177 -0
- package/dist/ui/fleet-office.js +434 -0
- package/dist/ui/fleet-org.js +21 -8
- package/dist/ui/fleet-route-scene.js +272 -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 +482 -0
- package/dist/ui/fleet-task-work.js +107 -0
- package/dist/ui/fleet-tasks.js +569 -0
- package/dist/ui/fleet-traffic.js +227 -45
- package/dist/ui/fleet-usage.js +36 -2
- package/dist/ui/guest-refused.html +41 -0
- package/dist/ui/icons/icon-192.png +0 -0
- package/dist/ui/icons/icon-512.png +0 -0
- package/dist/ui/image-lightbox.js +45 -1
- package/dist/ui/image-zoom.js +242 -0
- package/dist/ui/panel-chat.js +282 -89
- package/dist/ui/panel-details.js +2 -0
- package/dist/ui/panel-fleet.js +32 -71
- package/dist/ui/panel-needs.js +23 -6
- package/dist/ui/panel-settings.js +158 -32
- package/dist/ui/preview-panel.js +2 -1
- package/dist/ui/search-dialog.js +350 -0
- package/dist/ui/settings-appearance.js +170 -10
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-dialogs.js +46 -21
- package/dist/ui/settings-discord.js +6 -2
- package/dist/ui/settings-guests.js +2 -1
- package/dist/ui/settings-learn.js +1 -0
- package/dist/ui/settings-model.js +51 -18
- package/dist/ui/settings-mods.js +8 -3
- package/dist/ui/settings-owner-effects.js +6 -4
- package/dist/ui/settings-strings.js +180 -6
- package/dist/ui/settings-token.js +3 -1
- package/dist/ui/settings-web-authority.js +13 -5
- package/dist/ui/settings-wizard.js +13 -7
- package/dist/ui/shared/agend-auth.js +3 -1
- package/dist/ui/shared/app-i18n.js +12 -5
- package/dist/ui/shared/app-needs.js +2 -2
- package/dist/ui/shared/app-prefs.js +15 -0
- package/dist/ui/shared/app-route.js +18 -0
- package/dist/ui/shared/app-shell.js +172 -28
- package/dist/ui/shared/app-store.js +3 -2
- package/dist/ui/shared/app-stream.js +7 -2
- package/dist/ui/shared/app-themes.js +116 -1
- package/dist/ui/shared/app.css +681 -54
- package/dist/ui/shared/app.js +9 -1
- package/dist/ui/shared/card-strings.js +4 -0
- package/dist/ui/shared/effect-app-runtime.js +7 -5
- package/dist/ui/shared/effect-chat-runtime.js +2 -7
- package/dist/ui/shared/effect-cursor.js +3 -2
- package/dist/ui/shared/effect-display-metadata.js +39 -0
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-policy.js +2 -2
- package/dist/ui/shared/effect-registry.js +30 -11
- package/dist/ui/shared/effect-runtime-loader.js +3 -1
- package/dist/ui/shared/effect-stock-snapshot.js +9 -0
- package/dist/ui/shared/effect-stock-trust.js +40 -9
- package/dist/ui/shared/effect-trial-source.js +1 -1
- package/dist/ui/shared/effect-trial-stage.js +27 -21
- package/dist/ui/shared/effect-trial.css +1 -1
- package/dist/ui/shared/feature-flags.js +127 -0
- package/dist/ui/shared/guest-refused.js +35 -0
- package/dist/ui/shared/header-tools.js +2 -2
- package/dist/ui/shared/identity-card.js +26 -8
- package/dist/ui/shared/identity-color.js +17 -10
- package/dist/ui/shared/instance-nav.js +183 -28
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/panel-view.js +14 -29
- package/dist/ui/shared/text-undo.js +210 -0
- package/dist/ui/shared/tokens.css +13 -3
- package/dist/ui/shared/ui-dialog.js +5 -4
- package/dist/ui/shared/ui-icons.js +4 -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 +206 -16
- package/dist/ui/shared/view-strings.js +68 -4
- package/dist/ui/shared/web-authorize.js +50 -1
- package/dist/ui/signin.html +2 -0
- package/dist/ui/web-terminal/terminal.css +4 -4
- package/dist/ui/web-terminal/terminal.html +10 -10
- package/dist/ui/web-terminal/terminal.js +58 -12
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.js +1 -1
- package/dist/update-dispatch.js.map +1 -1
- package/dist/update-install.js.map +1 -1
- package/dist/update-launch.d.ts +10 -1
- package/dist/update-launch.js +39 -14
- package/dist/update-launch.js.map +1 -1
- package/dist/update-marker.js.map +1 -1
- package/dist/update-preflight.js +1 -1
- package/dist/update-preflight.js.map +1 -1
- package/dist/update-progress.d.ts +3 -1
- package/dist/update-progress.js +3 -1
- package/dist/update-progress.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 +89 -2
- package/dist/usage/providers.js +247 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/usage/usage-api.d.ts +5 -1
- package/dist/usage/usage-api.js +185 -58
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.js +1 -1
- package/dist/usage-rollup.js.map +1 -1
- 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 +7 -0
- package/dist/view-api.js +16 -4
- package/dist/view-api.js.map +1 -1
- package/dist/wake-coordinator.js.map +1 -1
- package/dist/web-ambient.js +9 -2
- package/dist/web-ambient.js.map +1 -1
- package/dist/web-api.d.ts +58 -10
- package/dist/web-api.js +1104 -71
- package/dist/web-api.js.map +1 -1
- package/dist/web-app-icon-worker.d.ts +1 -0
- package/dist/web-app-icon-worker.js +16 -0
- package/dist/web-app-icon-worker.js.map +1 -0
- package/dist/web-app-icon.d.ts +109 -0
- package/dist/web-app-icon.js +257 -0
- package/dist/web-app-icon.js.map +1 -0
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.d.ts +1 -0
- package/dist/web-appearance-tools.js +7 -3
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.d.ts +4 -10
- package/dist/web-appearance.js +7 -4
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-auth.d.ts +8 -4
- package/dist/web-auth.js +33 -21
- 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.js.map +1 -1
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +118 -8
- package/dist/web-chat-history.js +220 -25
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +5 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-cookie-names.d.ts +5 -0
- package/dist/web-cookie-names.js +12 -0
- package/dist/web-cookie-names.js.map +1 -0
- package/dist/web-effect-bundle.d.ts +2 -2
- package/dist/web-effect-library.js.map +1 -1
- package/dist/web-effect-playback.js.map +1 -1
- package/dist/web-effect-profiles.d.ts +16 -16
- package/dist/web-effect-profiles.js +3 -2
- package/dist/web-effect-profiles.js.map +1 -1
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect.d.ts +6 -6
- package/dist/web-effect.js.map +1 -1
- package/dist/web-experimental-http.d.ts +2 -0
- package/dist/web-experimental-http.js +12 -0
- package/dist/web-experimental-http.js.map +1 -0
- package/dist/web-experimental.d.ts +11 -0
- package/dist/web-experimental.js +49 -0
- package/dist/web-experimental.js.map +1 -0
- package/dist/web-guest-access.d.ts +4 -2
- package/dist/web-guest-access.js +22 -10
- package/dist/web-guest-access.js.map +1 -1
- package/dist/web-guest-rooms.js.map +1 -1
- 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-icons.d.ts +33 -1
- package/dist/web-icons.js +83 -11
- package/dist/web-icons.js.map +1 -1
- package/dist/web-identity-color.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-images.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.js.map +1 -1
- package/dist/web-mentions.js.map +1 -1
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-store.d.ts +2 -0
- package/dist/web-mod-store.js +10 -0
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-office-store.d.ts +104 -0
- package/dist/web-office-store.js +236 -0
- package/dist/web-office-store.js.map +1 -0
- 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-owner-css.js.map +1 -1
- package/dist/web-png.d.ts +33 -0
- package/dist/web-png.js +329 -0
- package/dist/web-png.js.map +1 -0
- package/dist/web-prefs.d.ts +6 -0
- package/dist/web-prefs.js +29 -3
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +2 -0
- package/dist/web-preview.js +2 -0
- package/dist/web-preview.js.map +1 -1
- package/dist/web-profile.js.map +1 -1
- package/dist/web-reactions.d.ts +35 -0
- package/dist/web-reactions.js +47 -0
- package/dist/web-reactions.js.map +1 -0
- package/dist/web-request-context.d.ts +5 -0
- package/dist/web-request-context.js.map +1 -1
- package/dist/web-returning-device.d.ts +4 -2
- package/dist/web-returning-device.js +13 -6
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-schedules.js.map +1 -1
- package/dist/web-send-dedupe.d.ts +36 -0
- package/dist/web-send-dedupe.js +69 -0
- package/dist/web-send-dedupe.js.map +1 -0
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.js +1 -1
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +11 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.d.ts +6 -0
- package/dist/web-settings-tools.js +52 -17
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-terminal-http.js +15 -2
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-terminal.js +1 -1
- package/dist/web-terminal.js.map +1 -1
- package/dist/web-theme-store.d.ts +2 -2
- package/dist/web-theme-store.js +6 -3
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-theme.d.ts +29 -0
- package/dist/web-theme.js +89 -1
- package/dist/web-theme.js.map +1 -1
- package/dist/web-upload.d.ts +18 -1
- package/dist/web-upload.js +45 -7
- package/dist/web-upload.js.map +1 -1
- package/dist/web-widget.js.map +1 -1
- package/dist/webhook-emitter.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/ws-server.js.map +1 -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 +828 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/launcher/private-home.cjs +43 -0
- package/package.json +16 -13
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
package/dist/ui/shared/app.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
// #1665 first: the host's preferences go into this browser's cache before any module below reads its key.
|
|
9
9
|
import { bootPrefs } from "./app-prefs.js";
|
|
10
10
|
import { html, render } from "./app-html.js";
|
|
11
|
-
import { Shell, handleKey, showDialog, closeDrawer, openDrawer, shellStore, retryable, setNewInstanceOpener } from "./app-shell.js";
|
|
11
|
+
import { Shell, handleKey, handleSearchKey, showDialog, closeDrawer, openDrawer, shellStore, retryable, setNewInstanceOpener, isMacLike } from "./app-shell.js";
|
|
12
12
|
import { installSwipe } from "./app-swipe.js";
|
|
13
|
+
import { installTextUndo } from "./text-undo.js";
|
|
13
14
|
import { startRouter, navStore, navigate } from "./app-nav.js";
|
|
14
15
|
import { createStream } from "./app-stream.js";
|
|
15
16
|
import { appStore, applyStatus, applyActivity, guestPage } from "./app-store.js";
|
|
@@ -93,6 +94,8 @@ if (mode === "full") {
|
|
|
93
94
|
panels.set("log", { load: () => loadLog().then((m) => m.LogPanel) });
|
|
94
95
|
// #1386 §6.3: desktop notifications for new "Needs you" items, in any panel, while this signed-in page is open.
|
|
95
96
|
startNeedsNotifier({ open: (instance) => navigate(chatPath(instance)) });
|
|
97
|
+
// #2233: a backend sign-in running anywhere is shown on every admin page (the module lives behind the session gate).
|
|
98
|
+
import("/ui/js/backend-signin.js").then((m) => m.installSignIn(), () => {});
|
|
96
99
|
}
|
|
97
100
|
// #1665: this device's first upload of its own choices (once), then another device's changes at each status frame.
|
|
98
101
|
// A guest's page only reads them (prefsWritable is false there).
|
|
@@ -121,6 +124,11 @@ if (!guest) installOwnerCss();
|
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
document.addEventListener("keydown", handleKey);
|
|
127
|
+
// #2293: Ctrl+K / ⌘K (and Ctrl+F in a chat) — an admin's full app only; the server refuses a guest's search anyway.
|
|
128
|
+
if (mode === "full" && !guest) document.addEventListener("keydown", handleSearchKey);
|
|
129
|
+
// #2342: Ctrl/⌘+Z and Ctrl+Shift+Z / Ctrl+Y / ⌘⇧Z in every text field, one history per field (the browser's is one
|
|
130
|
+
// for the whole page, and any script write wipes it).
|
|
131
|
+
installTextUndo({ mac: isMacLike() });
|
|
124
132
|
// #1605: on a phone (the sidebar is a drawer), swipe right in the main area to open it, left to close it — the same
|
|
125
133
|
// open/close as ☰ and the scrim. Nothing that owns a sideways drag (code, tables, the terminal, inputs, dialogs) and
|
|
126
134
|
// never the left edge (iOS: "back").
|
|
@@ -11,8 +11,10 @@ register("card", {
|
|
|
11
11
|
sizeSName: "Small", sizeMName: "Medium", sizeLName: "Large",
|
|
12
12
|
byHuman: "set by a person",
|
|
13
13
|
byAgent: "set by the agent",
|
|
14
|
+
menu: "Identity card",
|
|
14
15
|
show: "Show card",
|
|
15
16
|
hide: "Hide card",
|
|
17
|
+
showRow: "Show picture and bio",
|
|
16
18
|
bannerSafe: "Every screen",
|
|
17
19
|
bannerPhone: "Phone · M card",
|
|
18
20
|
},
|
|
@@ -24,8 +26,10 @@ register("card", {
|
|
|
24
26
|
sizeSName: "小", sizeMName: "中", sizeLName: "大",
|
|
25
27
|
byHuman: "由人設定",
|
|
26
28
|
byAgent: "由 agent 設定",
|
|
29
|
+
menu: "身分卡",
|
|
27
30
|
show: "顯示卡片",
|
|
28
31
|
hide: "隱藏卡片",
|
|
32
|
+
showRow: "顯示小圖和介紹",
|
|
29
33
|
bannerSafe: "所有螢幕",
|
|
30
34
|
bannerPhone: "手機 · 中卡片",
|
|
31
35
|
},
|
|
@@ -13,7 +13,7 @@ const episodes = new WeakSet();
|
|
|
13
13
|
|
|
14
14
|
/** `current` belongs to the page/session episode. Route cleanup only releases its contribution. */
|
|
15
15
|
export function createAppEffectRuntime({ window: host, current, observe, onChange = () => {}, onDispose = () => {}, resolveOwnerTarget = null, onOwnerUnavailable = () => {}, factories = {} }) {
|
|
16
|
-
let dead = false, error = null, loader = null, registry = null, writer = null, source = null, personal = null, trial = null, pending = null, lastMetadata = null, serial = 0, revision = 0, stamp = null, syncing = false, queued = false;
|
|
16
|
+
let dead = false, claimed = false, error = null, loader = null, registry = null, writer = null, source = null, personal = null, trial = null, pending = null, lastMetadata = null, serial = 0, revision = 0, stamp = null, syncing = false, queued = false;
|
|
17
17
|
const bindings = new Map(), profiles = new Map();
|
|
18
18
|
let lastContext = null, playbackUnavailable = null;
|
|
19
19
|
const identity = effectPlaybackIdentity(host), auth = host?.AgendAuth;
|
|
@@ -26,7 +26,7 @@ export function createAppEffectRuntime({ window: host, current, observe, onChang
|
|
|
26
26
|
};
|
|
27
27
|
const placementIdentity = p => JSON.stringify([p.by, p.manifest.layer, p.params]);
|
|
28
28
|
const clock = () => host.performance.now();
|
|
29
|
-
let offAuth = null;
|
|
29
|
+
let offAuth = null, disposed = null;
|
|
30
30
|
const snapshot = s => {
|
|
31
31
|
const effects = s?.metadata?.effects ?? [], known = registry?.snapshot?.() ?? [];
|
|
32
32
|
const rows = effects.map(p => {
|
|
@@ -76,16 +76,18 @@ export function createAppEffectRuntime({ window: host, current, observe, onChang
|
|
|
76
76
|
if (pending?.source === s) safe(() => pending.controller.abort());
|
|
77
77
|
revision++; stamp = null;
|
|
78
78
|
}
|
|
79
|
-
function dispose() {
|
|
80
|
-
if (dead) return; dead = true; discard(source);
|
|
79
|
+
function dispose(restartable = false) {
|
|
80
|
+
if (dead) return disposed; dead = true; discard(source);
|
|
81
81
|
safe(() => trial?.dispose()); safe(() => pending?.controller.abort()); safe(() => registry?.dispose?.()); safe(() => loader?.dispose?.()); safe(() => personal?.dispose()); safe(() => writer?.dispose()); safe(() => offAuth?.());
|
|
82
82
|
safe(() => host?.removeEventListener?.("pagehide", dispose));
|
|
83
83
|
for (const row of profiles.values()) safe(() => row.collector.dispose()); profiles.clear(); bindings.clear(); safe(() => onDispose({ error }));
|
|
84
|
+
disposed = Promise.all([safe(() => loader?.whenDisposed?.()), safe(() => registry?.whenDisposed?.())]).then(() => { if (restartable === true && claimed) episodes.delete(host); });
|
|
85
|
+
return disposed;
|
|
84
86
|
}
|
|
85
87
|
function fail(reason) { if (dead) return; error = reason; dispose(); safe(() => onChange({ error, rows: [], effects: [], loading: false })); }
|
|
86
88
|
const unavailable = { ok: false, sync() {}, changedChat() {}, reply() {}, detachChat() {}, attachChat() { return null; }, attachTrial() { return null; }, stopTrial() {}, trialSnapshot: () => ({ rows: [] }), snapshot: () => snapshot(null), dispose };
|
|
87
89
|
if (!host || typeof host !== "object" || episodes.has(host) || !identity || typeof current !== "function" || typeof observe !== "function" || typeof auth?.onSessionEnd !== "function" || typeof auth?.sessionEnded !== "function") return unavailable;
|
|
88
|
-
episodes.add(host); // Claim before invoking current/auth callbacks: one attempt per Window episode.
|
|
90
|
+
episodes.add(host); claimed = true; // Claim before invoking current/auth callbacks: one attempt per Window episode.
|
|
89
91
|
if (!alive()) { dispose(); return unavailable; }
|
|
90
92
|
try {
|
|
91
93
|
offAuth = auth.onSessionEnd(dispose);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { chatEffectIdentity } from "./effect-display-metadata.js";
|
|
1
2
|
/** #1629: one committed local Chat lease joins the reviewed host-only effect primitives. */
|
|
2
3
|
import { createEffectRuntimeLoader } from "./effect-runtime-loader.js";
|
|
3
4
|
import { createEffectRegistry } from "./effect-registry.js";
|
|
@@ -43,13 +44,7 @@ export function createEffectWriter(host, current) {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/** Frozen, server-rendered session identity only. A header-token/public/View load has no identity. */
|
|
46
|
-
export
|
|
47
|
-
try {
|
|
48
|
-
const b = host.document.body.dataset, x = JSON.parse(host.document.documentElement.getAttribute("data-prefs") || "null");
|
|
49
|
-
if (b.mode !== "full" || b.tier === "guest" || b.publicLink === "1" || b.webTransport === "poll" || !["person", "operator"].includes(x?.ownerScope) || x.unreadable === true || typeof x.ownerEpoch !== "string" || !/^[a-f0-9]{16}$/.test(x.ownerEpoch)) return null;
|
|
50
|
-
return Object.freeze({ epoch: x.ownerEpoch, scope: x.ownerScope });
|
|
51
|
-
} catch { return null; }
|
|
52
|
-
}
|
|
47
|
+
export { chatEffectIdentity } from "./effect-display-metadata.js";
|
|
53
48
|
/** Chat-only public/guest capability stays separate from personal preferences and management. */
|
|
54
49
|
export function effectPlaybackIdentity(host) {
|
|
55
50
|
try {
|
|
@@ -25,9 +25,10 @@ export function createEffectCursor({ window: host, current, readImage, onChange
|
|
|
25
25
|
const unavailable = { ok: false, update() {}, snapshot: () => ({ status: "unavailable", id: null }), dispose() {} };
|
|
26
26
|
if (!host?.document || owners.has(host) || ![current, readImage, onChange, host.getComputedStyle, host.Blob, host.URL?.createObjectURL, host.URL?.revokeObjectURL, host.AbortController, host.setTimeout, host.clearTimeout, host.performance?.now].every(x => typeof x === "function")) return unavailable;
|
|
27
27
|
const token = {}; owners.set(host, token);
|
|
28
|
+
let finishDisposed; const disposed = new Promise(resolve => { finishDisposed = resolve; });
|
|
28
29
|
const doc = host.document; let dead = false, previous = null, wanted = null, pending = null, active = null, blocked = null, generation = 0, checking = false, notifying = false, status = "off";
|
|
29
30
|
const safe = fn => { try { return fn(); } catch { return null; } };
|
|
30
|
-
const release = () => { if (dead && !pending
|
|
31
|
+
const release = () => { if (dead && !pending) { if (owners.get(host) === token) owners.delete(host); finishDisposed(); } };
|
|
31
32
|
function alive() {
|
|
32
33
|
if (dead || checking) return false;
|
|
33
34
|
checking = true; const value = safe(() => current() === true && host.document === doc); checking = false;
|
|
@@ -121,5 +122,5 @@ export function createEffectCursor({ window: host, current, readImage, onChange
|
|
|
121
122
|
}
|
|
122
123
|
start(); tell();
|
|
123
124
|
}
|
|
124
|
-
return { ok: true, update, snapshot, dispose };
|
|
125
|
+
return { ok: true, update, snapshot, dispose, whenDisposed: () => disposed };
|
|
125
126
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** #1629: closed host display metadata. Neither this object nor its token grants a trial read. */
|
|
2
|
+
const KEYS = ["v", "offer", "id", "title", "expiresAt"], ID = /^[0-9a-f]{32}$/;
|
|
3
|
+
const FORBIDDEN = /(?!\u200d)[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
|
|
4
|
+
const VISIBLE = /[^\p{M}\p{C}\p{Z}\u115f\u1160\u3164\uffa0\u2800]/u;
|
|
5
|
+
let graphemes = null;
|
|
6
|
+
export function checkEffectTrialOffer(value) {
|
|
7
|
+
try {
|
|
8
|
+
if (!value || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return null;
|
|
9
|
+
const keys = Reflect.ownKeys(value);
|
|
10
|
+
if (keys.length !== KEYS.length || keys.some(k => typeof k !== "string" || !KEYS.includes(k))) return null;
|
|
11
|
+
const x = Object.create(null);
|
|
12
|
+
for (const key of KEYS) {
|
|
13
|
+
const d = Object.getOwnPropertyDescriptor(value, key);
|
|
14
|
+
if (!d || !("value" in d) || !d.enumerable) return null;
|
|
15
|
+
x[key] = d.value;
|
|
16
|
+
}
|
|
17
|
+
if (x.v !== 1 || typeof x.offer !== "string" || !ID.test(x.offer) || typeof x.id !== "string" || !ID.test(x.id)
|
|
18
|
+
|| typeof x.title !== "string" || x.title.length > 400 || x.title.normalize("NFC") !== x.title || x.title.trim() !== x.title
|
|
19
|
+
|| FORBIDDEN.test(x.title) || !VISIBLE.test(x.title) || !Number.isSafeInteger(x.expiresAt) || x.expiresAt < 0) return null;
|
|
20
|
+
graphemes ??= new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
21
|
+
let count = 0; for (const _part of graphemes.segment(x.title)) if (++count > 40) return null;
|
|
22
|
+
if (count < 1) return null;
|
|
23
|
+
return Object.freeze({ v: 1, offer: x.offer, id: x.id, title: x.title, expiresAt: x.expiresAt });
|
|
24
|
+
} catch { return null; }
|
|
25
|
+
}
|
|
26
|
+
/** Role and sender are host fields, never inferred from a message's text. Start must separately authorize. */
|
|
27
|
+
export function effectTrialMessage(message) {
|
|
28
|
+
if (!message || message.role !== "status" || message.sender !== "agend" || typeof message.instance !== "string"
|
|
29
|
+
|| message.instance.length < 1 || message.instance.length > 128) return null;
|
|
30
|
+
return checkEffectTrialOffer(message.effectTrial);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function chatEffectIdentity(host) {
|
|
34
|
+
try {
|
|
35
|
+
const b = host.document.body.dataset, x = JSON.parse(host.document.documentElement.getAttribute("data-prefs") || "null");
|
|
36
|
+
if (b.mode !== "full" || b.tier === "guest" || b.publicLink === "1" || b.webTransport === "poll" || !["person", "operator"].includes(x?.ownerScope) || x.unreadable === true || typeof x.ownerEpoch !== "string" || !/^[a-f0-9]{16}$/.test(x.ownerEpoch)) return null;
|
|
37
|
+
return Object.freeze({ epoch: x.ownerEpoch, scope: x.ownerScope });
|
|
38
|
+
} catch { return null; }
|
|
39
|
+
}
|
|
@@ -74,7 +74,14 @@ export function createOwnerEffectSource({ current, readMetadata, readResource, r
|
|
|
74
74
|
},
|
|
75
75
|
descriptors() {
|
|
76
76
|
if (!alive() || !metadata || error) return [];
|
|
77
|
-
const body = metadata, gen = generation
|
|
77
|
+
const body = metadata, gen = generation;
|
|
78
|
+
// #2188: the stock snapshot walks the whole page (thousands of computed styles). With no slot holding an effect
|
|
79
|
+
// that could play, there is nothing for it to admit: skipped — every page change (a status, a chat switch) ran it.
|
|
80
|
+
if (!SLOTS.some(slot => body.slots[slot]?.status === "available" && failed.get(slot) !== body.slots[slot].id)) {
|
|
81
|
+
for (const slot of SLOTS) drop(slot);
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const proof = safe(() => effectStockSnapshot(stock()));
|
|
78
85
|
if (!fresh(body, gen)) return [];
|
|
79
86
|
if (!proof) { clear(); return []; }
|
|
80
87
|
const result = [];
|
|
@@ -77,9 +77,9 @@ export function allocateEffectFrames(descriptors, context) {
|
|
|
77
77
|
if (!Array.isArray(descriptors) || descriptors.length > 128 || !plain(context)) return [];
|
|
78
78
|
const keys = new Set(), duplicate = new Set();
|
|
79
79
|
for (const d of descriptors) if (d && typeof d.key === "string") { if (keys.has(d.key)) duplicate.add(d.key); keys.add(d.key); }
|
|
80
|
-
const result = descriptors.map(d => ({ key: d?.key, verdict: "off", reason: "
|
|
80
|
+
const result = descriptors.map(d => ({ key: d?.key, verdict: "off", reason: "descriptor_invalid", queuePos: null }));
|
|
81
81
|
const gates = ["safe", "publicLink", "reducedMotion", "hidden", "enabled", "show", "transportReady", "constrained", "modal"];
|
|
82
|
-
if (gates.some(k => typeof context[k] !== "boolean") || context.openInstance !== null && !instanceName(context.openInstance)) return result;
|
|
82
|
+
if (gates.some(k => typeof context[k] !== "boolean") || context.openInstance !== null && !instanceName(context.openInstance)) return result.map(r => ({ ...r, reason: "gates_unknown" }));
|
|
83
83
|
let global = null;
|
|
84
84
|
if (context.safe === true) global = "safe_mode";
|
|
85
85
|
else if (context.reducedMotion === true) global = "reduced_motion";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { allocateEffectFrames, effectEvent, effectPlaybackReason } from "./effect-policy.js";
|
|
3
3
|
import { createOpaqueEffectFrame } from "./effect-frame.js";
|
|
4
4
|
import { createEffectGeometry, hostEffectRect } from "./effect-geometry.js";
|
|
5
|
-
import { effectStockSnapshot, effectStockAllows } from "./effect-stock-snapshot.js";
|
|
5
|
+
import { effectStockSnapshot, effectStockAllows, effectStockRefusal } from "./effect-stock-snapshot.js";
|
|
6
6
|
import { effectTrialStage, effectTrialStageIdentity, watchEffectTrialStage } from "./effect-trial-stage.js";
|
|
7
7
|
import { EffectBudget } from "./effect-profiler.js";
|
|
8
8
|
|
|
@@ -42,7 +42,8 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
42
42
|
try { if (!host?.document || !host.document.body || registries.has(host) || typeof load !== "function" || typeof stockSnapshot !== "function" || typeof onChange !== "function" || typeof onProfile !== "function" || typeof onMount !== "function" || typeof onRetire !== "function" || typeof clock !== "function" || !safety || ["allowed", "begin", "finish", "pause", "resume"].some(k => typeof safety[k] !== "function") || ["requestAnimationFrame", "cancelAnimationFrame", "setTimeout", "clearTimeout", "MutationObserver", "ResizeObserver", "AbortController"].some(k => typeof host[k] !== "function")) return { ok: false, reason: "registry_unsupported" }; } catch { return { ok: false, reason: "registry_unsupported" }; }
|
|
43
43
|
let dead = false, blocked = null, revision = 0, last = null, lastView = null, frameSerial = 0, context = null, descriptors = [], raf = null, timer = null;
|
|
44
44
|
const slots = new Map(), loads = new Set(), paused = new Map(), offs = [], observed = new Set(), failures = new Map(), results = new Map();
|
|
45
|
-
let
|
|
45
|
+
let finishDisposed; const disposed = new Promise(resolve => { finishDisposed = resolve; });
|
|
46
|
+
let readingStock = false, stockFailure = "stock_evidence_invalid", warned = null;
|
|
46
47
|
let root, geometry, observer, resize, longTasks = null, longTasksSupported = false;
|
|
47
48
|
const time = () => {
|
|
48
49
|
let n; try { n = clock(); } catch { return null; }
|
|
@@ -68,10 +69,14 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
68
69
|
const coverage = (d = null) => {
|
|
69
70
|
if (dead || blocked || readingStock) return null;
|
|
70
71
|
const before = revision; let proof = null; readingStock = true;
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
let failure = "stock_provider_failed";
|
|
73
|
+
try { const raw = stockSnapshot(Object.freeze({ frameRoot: root })); proof = effectStockSnapshot(raw); failure = proof ? null : effectStockRefusal(raw); }
|
|
74
|
+
catch { /* unavailable stays denied, with a local diagnostic */ }
|
|
73
75
|
finally { readingStock = false; }
|
|
74
76
|
if (dead || blocked || before !== revision) return null;
|
|
77
|
+
stockFailure = failure;
|
|
78
|
+
if (failure !== warned) { warned = failure; if (failure) { try { host.console?.warn("[AgEnD effects] Playback blocked:", failure); } catch { /* display only */ } } }
|
|
79
|
+
if (dead || blocked || before !== revision) return null;
|
|
75
80
|
return d === null || permits(d, proof) ? proof : null;
|
|
76
81
|
};
|
|
77
82
|
const position = (d, proof) => d.trialStage ? localStage(d, proof)?.rect ?? null : hostEffectRect(d.element);
|
|
@@ -150,7 +155,7 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
150
155
|
const shown = why => (why === "gates_unknown" && !eligible() && gateReason()) || why;
|
|
151
156
|
function view() {
|
|
152
157
|
return descriptors.map(d => {
|
|
153
|
-
const r = results.get(d.key) ?? { verdict: "off", reason: blocked ?? (
|
|
158
|
+
const r = results.get(d.key) ?? { verdict: "off", reason: blocked ?? (eligible() ? stockFailure : gateReason()) ?? "runtime_unavailable", queuePos: null }, s = slots.get(d.key);
|
|
154
159
|
// #2055 one display precedence: a global latch, then the sticky safety history, then this page's own pause/failure.
|
|
155
160
|
const n = named.get(d.key), sticky = n && n.identity === signature(d) ? n.reason : null;
|
|
156
161
|
return { key: d.key, id: d.id, ...r, ...(sticky && r.verdict === "queued" ? { verdict: "off", queuePos: null } : {}), phase: s?.frame ? s.ready ? "running" : "starting" : s ? "loading" : null,
|
|
@@ -173,7 +178,7 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
173
178
|
};
|
|
174
179
|
function observe() {
|
|
175
180
|
const nodes = host.document.querySelectorAll("[data-trust]");
|
|
176
|
-
if (nodes.length >
|
|
181
|
+
if (nodes.length > 4096) throw Error("trust coverage unavailable");
|
|
177
182
|
const wanted = new Set([host.document.documentElement, ...nodes]);
|
|
178
183
|
for (const d of descriptors) if (d.element?.ownerDocument === host.document && d.element.isConnected === true) wanted.add(d.element);
|
|
179
184
|
for (const n of observed) if (!wanted.has(n)) { resize.unobserve(n); observed.delete(n); }
|
|
@@ -185,7 +190,14 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
185
190
|
const proposal = revision;
|
|
186
191
|
if (time() === null) blocked = "clock_unavailable";
|
|
187
192
|
const hidden = context?.hidden === true || host.document.visibilityState !== "visible";
|
|
193
|
+
// #2188: nothing to place, nothing to prove — the stock walk (thousands of computed styles) is not run for an empty
|
|
194
|
+
// list; a frame still held is retired as superseded, exactly as an allocation of nothing would.
|
|
195
|
+
if (!blocked && descriptors.length === 0) {
|
|
196
|
+
for (const s of [...slots.values()]) { retire(s, "superseded"); if (dead || proposal !== revision) return; }
|
|
197
|
+
results.clear(); tell(); return;
|
|
198
|
+
}
|
|
188
199
|
const stock = eligible() ? coverage() : null;
|
|
200
|
+
if (dead || proposal !== revision) return;
|
|
189
201
|
if (blocked || !eligible() || !stock) {
|
|
190
202
|
if (!stopAll(blocked ?? "gates_unknown")) return;
|
|
191
203
|
results.clear();
|
|
@@ -234,7 +246,11 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
234
246
|
if (s.frame && s.hiddenSince !== null) { s.hiddenSince = null; s.healthySince = last; if (s.budget.gates({ hidden: false, reducedMotion: false, saveData: false, show: true }).remove) retire(s, "hidden"); }
|
|
235
247
|
if (dead || proposal !== revision) return;
|
|
236
248
|
}
|
|
237
|
-
try { observe(); } catch {
|
|
249
|
+
try { observe(); } catch {
|
|
250
|
+
if (dead || proposal !== revision || !stopAll("trust_geometry_unknown")) return;
|
|
251
|
+
for (const d of descriptors) results.set(d.key, { verdict: "off", reason: "trust_geometry_unknown", queuePos: null });
|
|
252
|
+
tell(); return;
|
|
253
|
+
}
|
|
238
254
|
const max = context.constrained ? 1 : 3;
|
|
239
255
|
for (const d of descriptors) {
|
|
240
256
|
if (!chosen.has(d.key) || slots.has(d.key)) continue;
|
|
@@ -327,7 +343,7 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
327
343
|
}).catch(() => { if (current(s)) retire(s, "resource_unavailable"); }).finally(() => {
|
|
328
344
|
if (request.timer !== null) host.clearTimeout(request.timer);
|
|
329
345
|
loads.delete(request); if (s.request === request) s.request = null;
|
|
330
|
-
if (!dead) reconcile(); else if (loads.size === 0
|
|
346
|
+
if (!dead) reconcile(); else if (loads.size === 0) { if (registries.get(host) === api) registries.delete(host); finishDisposed(); }
|
|
331
347
|
});
|
|
332
348
|
}
|
|
333
349
|
schedule(); tell();
|
|
@@ -431,7 +447,8 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
431
447
|
} catch { return false; }
|
|
432
448
|
}
|
|
433
449
|
function pointer(event) {
|
|
434
|
-
|
|
450
|
+
// #2188: no frame to forward to — no gate to read (each read walks the page's computed styles, per pointer event).
|
|
451
|
+
if (dead || blocked || slots.size === 0 || !pointerGate() || event.isTrusted !== true) return;
|
|
435
452
|
const kinds = { pointermove: "move", pointerdown: "down", pointerup: "up", click: "click", wheel: "wheel" }, kind = kinds[event.type];
|
|
436
453
|
if (!kind || !finite(event.clientX) || !finite(event.clientY) || Math.abs(event.clientX) > 1e7 || Math.abs(event.clientY) > 1e7 || !Number.isInteger(event.buttons) || event.buttons < 0 || event.buttons > 31) return;
|
|
437
454
|
try { const target = host.document.elementFromPoint(event.clientX, event.clientY); if (!target || typeof target.closest !== "function" || target.closest("[data-trust]")) return; } catch { return; }
|
|
@@ -502,7 +519,8 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
502
519
|
},
|
|
503
520
|
/** Host-only content-free signal API. Raw pointer publishing is refused; native pointer metadata is coalesced here. */
|
|
504
521
|
publish(type, fields, instance = null) {
|
|
505
|
-
|
|
522
|
+
// #2188: no frame to send to — nothing to prove (the stock walk ran twice on every page change).
|
|
523
|
+
if (dead || blocked || slots.size === 0 || !globalAllowed() || context.hidden || !coverage() || !TYPES.includes(type)) return 0;
|
|
506
524
|
const ts = time(); if (ts === null) { blocked = "clock_unavailable"; stopAll(blocked); tell(); return 0; }
|
|
507
525
|
let sent = 0; const proposal = revision;
|
|
508
526
|
for (const s of [...slots.values()]) {
|
|
@@ -513,11 +531,12 @@ export function createEffectRegistry({ window: host, origin, boot, load, safety,
|
|
|
513
531
|
}
|
|
514
532
|
return sent;
|
|
515
533
|
},
|
|
534
|
+
whenDisposed: () => disposed,
|
|
516
535
|
dispose() {
|
|
517
536
|
if (dead) return; dead = true; revision++; stopAll("disposed");
|
|
518
537
|
if (raf !== null) host.cancelAnimationFrame(raf); if (timer !== null) host.clearTimeout(timer);
|
|
519
538
|
observer.disconnect(); resize.disconnect(); longTasks?.disconnect(); for (const off of offs) off();
|
|
520
|
-
geometry.dispose(); root.remove(); observed.clear(); if (loads.size === 0
|
|
539
|
+
geometry.dispose(); root.remove(); observed.clear(); if (loads.size === 0) { if (registries.get(host) === api) registries.delete(host); finishDisposed(); }
|
|
521
540
|
},
|
|
522
541
|
};
|
|
523
542
|
// Read-only host geometry seam; no selector guessing among poster and live roots.
|
|
@@ -143,7 +143,8 @@ export function createEffectRuntimeLoader({ window: host, ownerEpoch, current, o
|
|
|
143
143
|
if (!host || typeof host !== "object" || loaders.has(host) || typeof host.fetch !== "function" || typeof host.AbortController !== "function" || typeof host.setTimeout !== "function" || typeof host.clearTimeout !== "function" || typeof ownerEpoch !== "string" || !EPOCH.test(ownerEpoch) || typeof current !== "function" || typeof onRevoke !== "function") return { ok: false };
|
|
144
144
|
const reservation = {}; loaders.set(host, reservation);
|
|
145
145
|
let dead = false, revoked = false, previous = null; const pending = new Set();
|
|
146
|
-
const
|
|
146
|
+
let finishDisposed; const disposed = new Promise(resolve => { finishDisposed = resolve; });
|
|
147
|
+
const releaseWindow = () => { if (dead && pending.size === 0) { if (loaders.get(host) === reservation) loaders.delete(host); finishDisposed(); } };
|
|
147
148
|
// Terminal state is latched before callbacks. Abort releases logical callers, never physical reservations.
|
|
148
149
|
function revoke(reason) {
|
|
149
150
|
if (dead || revoked) return;
|
|
@@ -215,6 +216,7 @@ export function createEffectRuntimeLoader({ window: host, ownerEpoch, current, o
|
|
|
215
216
|
}
|
|
216
217
|
const ownerRead = (signal, settled = false) => run("placements", `/ui/effects/owner?ownerEpoch=${ownerEpoch}`, checkEffectOwnerSlots, signal, settled);
|
|
217
218
|
return { ok: true,
|
|
219
|
+
whenDisposed: () => disposed,
|
|
218
220
|
owner(signal) { return ownerRead(signal); },
|
|
219
221
|
placements(instance, signal) { return placementRead(instance, signal); },
|
|
220
222
|
resource(input, signal) { return resourceRead(input, signal); },
|
|
@@ -32,3 +32,12 @@ export function effectStockAllows(snapshot, { layer, by } = {}) {
|
|
|
32
32
|
const proof = effectStockSnapshot(snapshot);
|
|
33
33
|
return !!proof && (layer === "behind" || layer === "front" && proof.front && (by === "human" || proof.agentFront));
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
/** Display only. Refused provider metadata never becomes paint evidence or authority. */
|
|
37
|
+
export function effectStockRefusal(value) {
|
|
38
|
+
try {
|
|
39
|
+
if (!plain(value)) return "stock_evidence_invalid";
|
|
40
|
+
const d = Object.getOwnPropertyDescriptor(value, "reason");
|
|
41
|
+
return d && Object.hasOwn(d, "value") && typeof d.value === "string" && /^[a-z][a-z0-9_]{0,79}$/.test(d.value) ? d.value : "stock_evidence_invalid";
|
|
42
|
+
} catch { return "stock_evidence_invalid"; }
|
|
43
|
+
}
|
|
@@ -11,10 +11,10 @@ const SPECS = [
|
|
|
11
11
|
["confirmation", ".shell > .pending-stack, .shell .p-settings > .panel-body > .col > .pending-stack.inline"], ["preview", ".shell .chat-split > .pv-panel, .shell .chat-split > .pv-divider"],
|
|
12
12
|
["preview-menu", ".shell .thread details.pv-menu"], ["palette", ".shell .dock .cmd-palette"],
|
|
13
13
|
["drop", ".shell .p-chat > .drop-overlay"],
|
|
14
|
-
["thread-control", ".shell .chat-main > .amb-note, .shell .p-chat .jump-latest, .shell .thread .msg-tools, .shell .thread .st-more, .shell .thread .cb-head, .shell .thread .cb-more, .shell .thread .tc-head, .shell .thread .tc-more, .shell .thread .pv-head, .shell .thread .pv-note, .shell .thread .pv-banner, .shell .thread .effect-trial-offer, .shell .thread .click-chip"],
|
|
14
|
+
["thread-control", ".shell .chat-main > .amb-note, .shell .p-chat .jump-latest, .shell .thread .msg-tools, .shell .thread .msg > div.msg-actions, .shell .thread .msg > button.msg-quote, .shell .thread .st-more, .shell .thread .cb-head, .shell .thread .cb-more, .shell .thread .tc-head, .shell .thread .tc-more, .shell .thread .pv-head, .shell .thread .pv-note, .shell .thread .pv-banner, .shell .thread .effect-trial-offer, .shell .thread .click-chip"],
|
|
15
15
|
["link", ".shell .thread .md a, .shell .thread .st-text > a.st-link, .shell .dock .prompts .txt > a.st-link"], ["attachment", ".shell .thread .atts"], ["media", ".shell .thread .att-media"],
|
|
16
16
|
["panel-navigation", ".shell .p-fleet > .seg, .shell .p-settings > .seg"],
|
|
17
|
-
["panel-content", ".shell .p-fleet > .panel-body, .shell .p-needs > .panel-body, .shell .p-settings > .panel-body, .shell .p-log > .panel-body, .shell .p-details > .panel-body, .shell .p-view > .panel-body, .shell .p-view > .v-term, .shell .p-view > .v-id
|
|
17
|
+
["panel-content", ".shell .p-fleet > .panel-body, .shell .p-needs > .panel-body, .shell .p-settings > .panel-body, .shell .p-log > .panel-body, .shell .p-details > .panel-body, .shell .p-view > .panel-body, .shell .p-view > .v-term, .shell .p-view > .v-id"],
|
|
18
18
|
["panel-controls", ".shell .p-log > .log-bar, .shell .p-settings > .s-pending"],
|
|
19
19
|
["session-ended", "body > .agend-session-ended[role=alert]"],
|
|
20
20
|
];
|
|
@@ -28,7 +28,7 @@ const PANELS = Object.freeze({
|
|
|
28
28
|
settings: { required: [".panel-head", ".seg", ".panel-body"], optional: [".s-pending"] },
|
|
29
29
|
log: { required: [".panel-head", ".panel-body"], optional: [".log-bar"] },
|
|
30
30
|
details: { required: [".panel-head", ".panel-body"], optional: [] },
|
|
31
|
-
view: { required: [".panel-head"], optional: [".panel-body", ".v-term", ".v-id"
|
|
31
|
+
view: { required: [".panel-head"], optional: [".panel-body", ".v-term", ".v-id"] },
|
|
32
32
|
});
|
|
33
33
|
function panelSurface(doc, chat) {
|
|
34
34
|
if (chat) return { panel: chat, structural: STRUCTURAL, content: CONTENT, kind: "chat" };
|
|
@@ -37,8 +37,8 @@ function panelSurface(doc, chat) {
|
|
|
37
37
|
const children = [...panel.children], count = selector => children.filter(el => el.matches(selector)).length;
|
|
38
38
|
if (spec.required.some(selector => count(selector) !== 1) || spec.optional.some(selector => count(selector) > 1)
|
|
39
39
|
|| children.some(el => !el.matches([...spec.required, ...spec.optional, "dialog.dlg", "dialog.lb"].join(",")))) return null;
|
|
40
|
-
if (kind === "view" && !(count(".panel-body") === 1 && !count(".v-term") && !count(".v-id")
|
|
41
|
-
|| !count(".panel-body") && count(".v-term") === 1 && count(".v-
|
|
40
|
+
if (kind === "view" && !(count(".panel-body") === 1 && !count(".v-term") && !count(".v-id")
|
|
41
|
+
|| !count(".panel-body") && count(".v-term") === 1 && count(".v-id") === 1)) return null;
|
|
42
42
|
const prefix = `.p-${kind} > `;
|
|
43
43
|
return { panel, kind, structural: [...STRUCTURAL.slice(0, 5), `.main > .p-${kind}`],
|
|
44
44
|
content: [...CONTENT.filter(selector => !selector.startsWith(".p-chat") && !selector.startsWith(".chat-main")),
|
|
@@ -115,13 +115,36 @@ function stockBannerFill(host, el) {
|
|
|
115
115
|
if (b.display !== "block" || el.offsetParent !== box) return null;
|
|
116
116
|
return rect(box);
|
|
117
117
|
}
|
|
118
|
+
function zeroClipMargin(host, style) {
|
|
119
|
+
const margin = style.overflowClipMargin ?? style.getPropertyValue?.("overflow-clip-margin");
|
|
120
|
+
// WebKit versions without this property still implement paint containment. An absent
|
|
121
|
+
// computed value is usable only when the engine explicitly reports it unsupported;
|
|
122
|
+
// unknown capability or a supported but unreadable/expanded margin cannot prove a box.
|
|
123
|
+
return margin === "0px" || [undefined, ""].includes(margin)
|
|
124
|
+
&& host.CSS?.supports?.("overflow-clip-margin", "1px") === false;
|
|
125
|
+
}
|
|
118
126
|
function protectedPaint(host, root, budget) {
|
|
127
|
+
// These two stock toolbar boxes physically clip ALL descendants, including fixed-position
|
|
128
|
+
// children. Their entire box is a hole; descendant ink cannot escape it. Inline, fragmented,
|
|
129
|
+
// expanded-clip or CSS-overridden boxes take the ordinary bounded walk instead.
|
|
130
|
+
const s = host.getComputedStyle(root);
|
|
131
|
+
if (root.matches?.(".shell .thread .msg-tools, .shell .thread .codeblock > .cb-head") && s.contain === "paint"
|
|
132
|
+
&& s.display === "flex" && s.overflowX === "clip" && s.overflowY === "clip" && zeroClipMargin(host, s)
|
|
133
|
+
&& none(s.filter) && none(s.backdropFilter) && s.borderImageSource === "none" && [undefined, "", "visible"].includes(s.contentVisibility) && root.getClientRects().length === 1) {
|
|
134
|
+
if (++budget.n > 4096) { budget.exceeded = true; return null; }
|
|
135
|
+
const r = rect(root), pad = outset(s);
|
|
136
|
+
// Containment clips descendants, not the root's own ink. Do not infer a world-space
|
|
137
|
+
// outset from local CSS lengths under a potentially transformed content ancestor.
|
|
138
|
+
if (!r || pad !== 0) return null;
|
|
139
|
+
return r;
|
|
140
|
+
}
|
|
119
141
|
const nodes = [root, ...root.querySelectorAll("*")]; budget.n += nodes.length;
|
|
120
|
-
if (budget.n > 4096) return null;
|
|
142
|
+
if (budget.n > 4096) { budget.exceeded = true; return null; }
|
|
121
143
|
let union = null;
|
|
122
144
|
for (const el of nodes) {
|
|
123
145
|
if (!visible(host, el)) continue;
|
|
124
146
|
const style = host.getComputedStyle(el), pad = outset(style);
|
|
147
|
+
if (style.borderImageSource !== undefined && style.borderImageSource !== "none" || ![undefined, "", "visible"].includes(style.contentVisibility)) return null;
|
|
125
148
|
const r = none(style.filter) ? rect(el) : stockBannerFill(host, el);
|
|
126
149
|
if (!r || pad === null || !none(style.backdropFilter)) return null;
|
|
127
150
|
const a = { x: r.x - pad, y: r.y - pad, width: r.width + pad * 2, height: r.height + pad * 2 };
|
|
@@ -165,15 +188,23 @@ export function stockEffectTrust(host, { frameRoot = null, ownerCss = "unknown"
|
|
|
165
188
|
if (s.position !== "relative" || s.zIndex !== "1" || !neutral(s)) return fail("stock_order_unknown");
|
|
166
189
|
}
|
|
167
190
|
const marked = [...doc.querySelectorAll("[data-trust]")], expected = new Set(), rects = [], budget = { n: 0 };
|
|
168
|
-
if (marked.length >
|
|
191
|
+
if (marked.length > 4096) return fail("stock_marker_limit");
|
|
169
192
|
for (const { kind, selector } of STOCK_TRUST_INVENTORY) for (const el of doc.querySelectorAll(selector)) {
|
|
170
193
|
if (el.ownerDocument !== doc || el.isConnected !== true || el.getAttribute("data-trust") !== kind) return fail("stock_trust_unknown");
|
|
171
194
|
expected.add(el);
|
|
172
195
|
}
|
|
173
196
|
if (marked.some(el => !expected.has(el)) || surface.kind === "chat" && !chat.querySelector('.dock[data-trust="composer"]') || !surface.panel.querySelector('.panel-head[data-trust="header"]')) return fail("stock_trust_unknown");
|
|
174
197
|
for (const el of marked) {
|
|
175
|
-
const bounds = protectedPaint(host, el, budget); if (!bounds) return fail("stock_paint_unknown");
|
|
176
|
-
|
|
198
|
+
const bounds = protectedPaint(host, el, budget); if (!bounds) return fail(budget.exceeded ? "stock_paint_limit" : "stock_paint_unknown");
|
|
199
|
+
// Off-screen history remains inventoried and paint-checked; it need not consume a
|
|
200
|
+
// viewport hole. Include the clip algorithm's extra 8px protection margin.
|
|
201
|
+
if (bounds.width && bounds.height && (!finite(host.innerHeight) || bounds.x + bounds.width + 8 >= 0 && bounds.y + bounds.height + 8 >= 0 && bounds.x - 8 <= host.innerWidth && bounds.y - 8 <= host.innerHeight)) rects.push(bounds);
|
|
202
|
+
}
|
|
203
|
+
// Keep the existing 128-hole transport bound. Conservative union may hide extra
|
|
204
|
+
// effect pixels; it can never reveal protected pixels, even for a dense viewport.
|
|
205
|
+
if (rects.length > 128) {
|
|
206
|
+
const rest = rects.splice(127), x = Math.min(...rest.map(r => r.x)), y = Math.min(...rest.map(r => r.y));
|
|
207
|
+
rects.push({ x, y, width: Math.max(...rest.map(r => r.x + r.width)) - x, height: Math.max(...rest.map(r => r.y + r.height)) - y });
|
|
177
208
|
}
|
|
178
209
|
if (doc.querySelector(".agend-session-ended")) return fail("session_ended");
|
|
179
210
|
let barrier = [...doc.querySelectorAll(BARRIERS)].some(el => visible(host, el));
|
|
@@ -64,7 +64,7 @@ export function createEffectTrialSource({ window: host, current, ownerCurrent, s
|
|
|
64
64
|
const lease = { identity, reply, stage, owner, current: x.current, onStop: x.onStop, startedAt: x.startedAt, until, dead: false, checking: false, pending: new Set(), timer: null, off: null, binding: null };
|
|
65
65
|
lease.binding = Object.freeze({ kind: "trial", key: identity.key, id: identity.id, source: lease, generation: identity.generation });
|
|
66
66
|
active = lease; used.add(stage.receipt);
|
|
67
|
-
lease.off = watchEffectTrialStage(stage.receipt,
|
|
67
|
+
lease.off = watchEffectTrialStage(stage.receipt, reason => stop(lease, typeof reason === "string" ? reason : "stage_ended"));
|
|
68
68
|
if (typeof lease.off !== "function" || constrainEffectTrialStage(stage.receipt, () => checked(lease)) !== true || !checked(lease)) { stop(lease, "stage_unavailable"); return null; }
|
|
69
69
|
try { arm(lease); } catch { stop(lease, "trial_unavailable"); return null; }
|
|
70
70
|
if (!checked(lease)) return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** #1629: host-issued LOCAL trial paint receipt. No authority, loader, frame factory or pool is created here. */
|
|
2
2
|
import { effectTrialShadow } from "./effect-trial-shadow.js";
|
|
3
3
|
import { effectHostStyle } from "./effect-host-style.js";
|
|
4
|
-
import { effectStockSnapshot } from "./effect-stock-snapshot.js";
|
|
4
|
+
import { effectStockSnapshot, effectStockRefusal } from "./effect-stock-snapshot.js";
|
|
5
5
|
import { STOCK_EFFECT_BARRIERS } from "./effect-stock-trust.js";
|
|
6
6
|
const receipts = new WeakMap(), owners = new WeakMap();
|
|
7
7
|
let serial = 0;
|
|
@@ -64,7 +64,8 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
64
64
|
if (!own || typeof current !== "function" || typeof onStop !== "function" || !host?.document || !panel || !stage || owners.has(stage)) return null;
|
|
65
65
|
const shell = effectTrialShadow(host, panel), hostSheet = effectHostStyle(host);
|
|
66
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;
|
|
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; };
|
|
68
69
|
const identity = Object.freeze({ key: own.key, id: own.id, instance: own.instance, generation: own.generation, serial: ++serial });
|
|
69
70
|
const invalidate = reason => {
|
|
70
71
|
if (dead) return; dead = true; receipts.delete(receipt); if (owners.get(stage) === receipt) owners.delete(stage);
|
|
@@ -76,45 +77,49 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
76
77
|
};
|
|
77
78
|
const blur = event => { if (event.target === host) invalidate("blur"); };
|
|
78
79
|
function check(stock) {
|
|
80
|
+
failure = "trial_layout_unverified";
|
|
79
81
|
try {
|
|
80
82
|
// This callback may reenter disposal or replace the owner. Recheck identity after it returns.
|
|
81
|
-
if (dead || current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt || dead) return
|
|
83
|
+
if (dead || current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt || dead) return reject("trial_current_changed");
|
|
82
84
|
const proof = effectStockSnapshot(stock), doc = host.document;
|
|
83
|
-
if (
|
|
85
|
+
if (!proof) return reject(effectStockRefusal(stock));
|
|
86
|
+
if (effectHostStyle(host) !== hostSheet || effectTrialShadow(host, panel) !== shell) return reject("trial_style_unavailable");
|
|
84
87
|
// The own panel MUST still suppress ordinary foreground effects. Never synthesize front:true.
|
|
85
|
-
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");
|
|
86
91
|
const split = doc.querySelector(".main > .p-chat > .chat-split");
|
|
87
92
|
if (!split || doc.querySelectorAll(".main > .p-chat").length !== 1 || doc.querySelectorAll(".chat-split > .pv-panel").length !== 1
|
|
88
|
-
|| panel.parentElement !== split || panel.ownerDocument !== doc || panel.isConnected !== true || panel.className !== "pv-panel effect-trial-panel" || panel.getAttribute("data-trust") !== "preview") 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");
|
|
89
94
|
const children = [...shell.root.children], names = ["effect-trial-style", "effect-trial-head", "effect-trial-controls", "effect-trial-body", "effect-trial-note"];
|
|
90
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
|
|
91
|
-
|| stage.className !== "effect-trial-stage" || stage.ownerDocument !== doc || stage.isConnected !== true || stage.hasAttribute("tabindex") || stage.hasAttribute("contenteditable")) return
|
|
96
|
+
|| stage.className !== "effect-trial-stage" || stage.ownerDocument !== doc || stage.isConnected !== true || stage.hasAttribute("tabindex") || stage.hasAttribute("contenteditable")) return reject("trial_shadow_unverified");
|
|
92
97
|
for (const control of [shell.head, shell.controls, shell.close, shell.stop, shell.note]) {
|
|
93
98
|
const style = host.getComputedStyle(control);
|
|
94
|
-
if (style.display === "none" || style.visibility !== "visible" || style.opacity !== "1" || !rect(control)) return
|
|
99
|
+
if (style.display === "none" || style.visibility !== "visible" || style.opacity !== "1" || !rect(control)) return reject("trial_controls_unavailable");
|
|
95
100
|
}
|
|
96
101
|
if ([...doc.querySelectorAll(STOCK_EFFECT_BARRIERS)].some(el => el !== panel && visible(host, el))
|
|
97
|
-
|| [...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");
|
|
98
103
|
const active = doc.activeElement;
|
|
99
|
-
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");
|
|
100
105
|
let el = stage, depth = 0;
|
|
101
|
-
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
|
|
102
|
-
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");
|
|
103
108
|
const s = host.getComputedStyle(stage), r = rect(stage), p = rect(panel);
|
|
104
109
|
if (!r || !p || s.position !== "relative" || s.zIndex !== "0" || s.overflowX !== "clip" || s.overflowY !== "clip"
|
|
105
110
|
|| s.paddingLeft !== "0px" || s.paddingRight !== "0px" || s.paddingTop !== "0px" || s.paddingBottom !== "0px"
|
|
106
111
|
|| ["borderLeftWidth", "borderRightWidth", "borderTopWidth", "borderBottomWidth"].some(k => s[k] !== "0px") || !none(s.boxShadow) || s.outlineStyle !== "none"
|
|
107
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
|
|
108
|
-
|| r.x < 0 || r.y < 0 || r.x + r.width > host.innerWidth || r.y + r.height > host.innerHeight) return
|
|
109
|
-
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");
|
|
110
115
|
const width = Math.floor(r.width), height = Math.floor(r.height);
|
|
111
|
-
if (width < 1 || height < 1 || width > 4096 || height > 4096 || width * height > 8388608 || dead || owners.get(stage) !== receipt) return
|
|
112
|
-
if (current(own) !== true || constraint !== null && constraint() !== true || dead || owners.get(stage) !== receipt || dead || stage.isConnected !== true || panel.parentElement !== split) return
|
|
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");
|
|
113
118
|
return { x: r.x, y: r.y, width, height };
|
|
114
|
-
} catch { return
|
|
119
|
+
} catch { return reject("trial_check_failed"); }
|
|
115
120
|
}
|
|
116
121
|
function project(stock) {
|
|
117
|
-
const r = check(stock); if (!r) { invalidate(
|
|
122
|
+
const r = check(stock); if (!r) { invalidate(failure); return null; }
|
|
118
123
|
return Object.freeze({ root: stage, rect: Object.freeze(r), identity, bind });
|
|
119
124
|
}
|
|
120
125
|
function bind(frame, { layer } = {}, stock) {
|
|
@@ -131,7 +136,7 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
131
136
|
};
|
|
132
137
|
const handle = { ok: true, element: frame, remove, hide,
|
|
133
138
|
sync(proof) {
|
|
134
|
-
const r = check(proof); if (!r || removed) { invalidate(
|
|
139
|
+
const r = check(proof); if (!r || removed) { invalidate(failure); return false; }
|
|
135
140
|
try {
|
|
136
141
|
const matches = visibility => {
|
|
137
142
|
const s = host.getComputedStyle(frame), actual = rect(frame);
|
|
@@ -146,7 +151,7 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
146
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");
|
|
147
152
|
if (!matches("hidden")) throw Error("local geometry lost");
|
|
148
153
|
rule.style.setProperty("visibility", "visible", "important"); shown = true; return true;
|
|
149
|
-
} catch { invalidate("
|
|
154
|
+
} catch { invalidate("trial_frame_geometry"); return false; }
|
|
150
155
|
},
|
|
151
156
|
};
|
|
152
157
|
frames.add(handle);
|
|
@@ -154,7 +159,8 @@ export function createEffectTrialStage({ window: host, panel, stage, binding: ra
|
|
|
154
159
|
const i = sheet.insertRule(`.${token}{}`, sheet.cssRules.length); rule = sheet.cssRules[i];
|
|
155
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");
|
|
156
161
|
frame.classList.add(token);
|
|
157
|
-
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 }; }
|
|
158
164
|
} catch { remove(); invalidate("stage_unavailable"); return { ok: false }; }
|
|
159
165
|
return handle;
|
|
160
166
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
overflow: clip !important;
|
|
17
17
|
background: #ffffff !important;
|
|
18
18
|
color: #1b1b1f !important;
|
|
19
|
-
font: 400 16px/1.4 system-ui, sans-serif !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
20
|
direction: ltr !important;
|
|
21
21
|
unicode-bidi: isolate !important;
|
|
22
22
|
text-align: start !important;
|