@songsid/agend 2.3.5-alpha.4 → 2.3.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/README.zh-TW.md +0 -2
- package/THIRD_PARTY_NOTICES.md +12 -28
- package/dist/agent-cli-instructions.md +1 -1
- package/dist/agent-credentials.d.ts +24 -0
- package/dist/agent-credentials.js +66 -0
- package/dist/agent-credentials.js.map +1 -0
- package/dist/agent-endpoint.d.ts +4 -6
- package/dist/agent-endpoint.js +15 -12
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/auth-api.d.ts +0 -21
- package/dist/auth-api.js +8 -93
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +30 -4
- package/dist/authority/session-authorizations.js +69 -17
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/authority/web-authority.d.ts +2 -12
- package/dist/authority/web-authority.js +4 -25
- package/dist/authority/web-authority.js.map +1 -1
- package/dist/backend/antigravity.js +3 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +12 -15
- package/dist/backend/claude-code.js +133 -152
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +14 -0
- package/dist/backend/codex-metadata.js +45 -0
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex-package.d.ts +2 -5
- package/dist/backend/codex-package.js +5 -1
- package/dist/backend/codex-package.js.map +1 -1
- package/dist/backend/codex-quota-history.d.ts +7 -0
- package/dist/backend/codex-quota-history.js +72 -0
- package/dist/backend/codex-quota-history.js.map +1 -0
- package/dist/backend/codex-session-lookup.d.ts +6 -0
- package/dist/backend/codex-session-lookup.js +1 -1
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex-speed.d.ts +14 -0
- package/dist/backend/codex-speed.js +35 -0
- package/dist/backend/codex-speed.js.map +1 -0
- package/dist/backend/codex.d.ts +116 -136
- package/dist/backend/codex.js +912 -942
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok-weekly-reset.d.ts +24 -0
- package/dist/backend/grok-weekly-reset.js +95 -0
- package/dist/backend/grok-weekly-reset.js.map +1 -0
- package/dist/backend/grok.d.ts +30 -3
- package/dist/backend/grok.js +301 -76
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -0
- package/dist/backend/kiro.js +50 -2
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +5 -3
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +15 -8
- package/dist/backend/types.js +3 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/bundled-tmux-guard.d.ts +21 -0
- package/dist/bundled-tmux-guard.js +96 -0
- package/dist/bundled-tmux-guard.js.map +1 -0
- package/dist/cache-ledger.d.ts +95 -0
- package/dist/cache-ledger.js +276 -4
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +5 -0
- package/dist/cache-service.js +16 -4
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.js +11 -3
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +51 -0
- package/dist/channel/adapters/telegram.js +235 -17
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/ipc-bridge.d.ts +0 -2
- package/dist/channel/mcp-tools.js +3 -3
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +2 -0
- package/dist/classic-channel-manager.d.ts +2 -0
- package/dist/classic-channel-manager.js +5 -1
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +14 -10
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +30 -71
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +3 -17
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +10 -0
- package/dist/cross-instance-notice.js +67 -5
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +70 -68
- package/dist/daemon.js +774 -846
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +8 -0
- package/dist/dashboard-permissions.js +16 -0
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +26 -16
- package/dist/delivery-consumed-watch.js +31 -26
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-outbox.d.ts +0 -5
- package/dist/delivery-outbox.js +4 -32
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +42 -2
- package/dist/delivery-reconciliation.js +164 -2
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/export-import.d.ts +7 -0
- package/dist/export-import.js +44 -10
- package/dist/export-import.js.map +1 -1
- package/dist/fleet-context.d.ts +4 -2
- package/dist/fleet-level-config.d.ts +1 -1
- package/dist/fleet-level-config.js +0 -2
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +108 -245
- package/dist/fleet-manager.js +656 -2028
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-instance.d.ts +0 -7
- package/dist/general-instance.js +3 -20
- package/dist/general-instance.js.map +1 -1
- package/dist/general-knowledge/skills/concepts/SKILL.md +393 -0
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
- package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +41 -4
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +9 -3
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/instance-config-impact.js +6 -7
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +19 -23
- package/dist/instance-lifecycle.js +216 -383
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-topic-delete.d.ts +77 -0
- package/dist/instance-topic-delete.js +123 -0
- package/dist/instance-topic-delete.js.map +1 -0
- package/dist/instructions.d.ts +1 -3
- package/dist/instructions.js +1 -7
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-engine-status.d.ts +11 -0
- package/dist/kiro-engine-status.js +6 -0
- package/dist/kiro-engine-status.js.map +1 -1
- package/dist/locale.js +63 -86
- package/dist/locale.js.map +1 -1
- package/dist/log-service.d.ts +28 -0
- package/dist/log-service.js +29 -0
- package/dist/log-service.js.map +1 -1
- package/dist/log-steps.d.ts +4 -3
- package/dist/log-steps.js +32 -7
- package/dist/log-steps.js.map +1 -1
- package/dist/logger.d.ts +16 -2
- package/dist/logger.js +346 -66
- package/dist/logger.js.map +1 -1
- package/dist/login-flows.d.ts +7 -0
- package/dist/login-flows.js +5 -2
- package/dist/login-flows.js.map +1 -1
- package/dist/login-manager.js +25 -4
- package/dist/login-manager.js.map +1 -1
- package/dist/missed-offline.d.ts +25 -0
- package/dist/missed-offline.js +79 -0
- package/dist/missed-offline.js.map +1 -0
- package/dist/muse-usage-relay.d.ts +2 -0
- package/dist/muse-usage-relay.js +5 -3
- package/dist/muse-usage-relay.js.map +1 -1
- package/dist/needs-you-hub.d.ts +6 -3
- package/dist/needs-you-hub.js +31 -9
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +20 -18
- package/dist/needs-you.js +18 -14
- package/dist/needs-you.js.map +1 -1
- package/dist/office-share-page.js +1 -1
- package/dist/office-share-page.js.map +1 -1
- package/dist/outbound-handlers.d.ts +2 -16
- package/dist/outbound-handlers.js +10 -72
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +0 -38
- package/dist/outbound-schemas.js +5 -14
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-quota-history.d.ts +7 -0
- package/dist/pane-quota-history.js +47 -0
- package/dist/pane-quota-history.js.map +1 -0
- package/dist/platform-general.d.ts +46 -0
- package/dist/platform-general.js +91 -0
- package/dist/platform-general.js.map +1 -0
- package/dist/public-web-gateway.js +0 -9
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +0 -11
- package/dist/public-web-link.js +0 -13
- package/dist/public-web-link.js.map +1 -1
- package/dist/queued-handoffs.d.ts +33 -0
- package/dist/queued-handoffs.js +75 -0
- package/dist/queued-handoffs.js.map +1 -0
- package/dist/quickstart-api.js +5 -9
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +8 -1
- package/dist/quickstart.js +42 -4
- package/dist/quickstart.js.map +1 -1
- package/dist/quota-notice-config.d.ts +22 -0
- package/dist/quota-notice-config.js +41 -0
- package/dist/quota-notice-config.js.map +1 -0
- package/dist/quota-notice.d.ts +7 -0
- package/dist/quota-notice.js +40 -0
- package/dist/quota-notice.js.map +1 -1
- package/dist/reply-buttons-controller.js +10 -6
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-polls.d.ts +2 -2
- package/dist/reply-polls.js +3 -3
- package/dist/reply-polls.js.map +1 -1
- package/dist/scheduler/db.d.ts +2 -1
- package/dist/scheduler/db.js +23 -9
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/task-board.d.ts +9 -0
- package/dist/scheduler/task-board.js +19 -0
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/settings-api.d.ts +13 -5
- package/dist/settings-api.js +26 -96
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +0 -1
- package/dist/settings-baseline.js +1 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.js +23 -28
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +1 -16
- package/dist/settings-confirmation.js +9 -47
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.d.ts +0 -4
- package/dist/settings-effect.js +1 -58
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +0 -4
- package/dist/settings-http-confirmation.js +3 -31
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +28 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/settings-request-capability.d.ts +0 -2
- package/dist/settings-request-capability.js +0 -4
- package/dist/settings-request-capability.js.map +1 -1
- package/dist/settings-transaction.d.ts +0 -4
- package/dist/settings-transaction.js +0 -9
- package/dist/settings-transaction.js.map +1 -1
- package/dist/setup-form.js +3 -6
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.js +0 -3
- package/dist/setup-i18n.js.map +1 -1
- package/dist/task-board-tool.d.ts +11 -0
- package/dist/task-board-tool.js +44 -0
- package/dist/task-board-tool.js.map +1 -1
- package/dist/task-board-waker.d.ts +6 -0
- package/dist/task-board-waker.js +4 -0
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-control.d.ts +1 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -2
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +5 -2
- package/dist/tool-permissions.js +7 -7
- package/dist/tool-permissions.js.map +1 -1
- package/dist/tool-progress.d.ts +2 -0
- package/dist/tool-progress.js +19 -3
- package/dist/tool-progress.js.map +1 -1
- package/dist/topic-commands.js +4 -3
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-delta-reader.d.ts +1 -1
- package/dist/transcript-delta-reader.js +1 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/transcript-monitor.d.ts +20 -3
- package/dist/transcript-monitor.js +92 -24
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +0 -5
- package/dist/transcript-sources.js +79 -8
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +3 -23
- package/dist/ui/app.html +8 -1
- package/dist/ui/backend-signin.js +21 -36
- package/dist/ui/chat-md-strings.js +9 -0
- package/dist/ui/chat-store.js +2 -13
- package/dist/ui/chat-strings.js +2 -50
- package/dist/ui/chat-thread.js +53 -3
- package/dist/ui/fleet-task-card.js +3 -3
- package/dist/ui/fleet-task-common.js +10 -0
- package/dist/ui/fleet-tasks.js +7 -5
- package/dist/ui/fleet-usage.js +90 -27
- package/dist/ui/panel-chat.js +37 -66
- package/dist/ui/panel-details.js +1 -2
- package/dist/ui/panel-fleet.js +88 -107
- package/dist/ui/panel-needs.js +21 -163
- package/dist/ui/panel-notices.js +4 -3
- package/dist/ui/panel-settings.js +149 -239
- package/dist/ui/preview-panel.js +84 -6
- package/dist/ui/search-dialog.js +3 -2
- package/dist/ui/settings-appearance.js +23 -122
- package/dist/ui/settings-catalog.js +10 -37
- package/dist/ui/settings-codex-copy.js +19 -0
- package/dist/ui/settings-confirm.js +1 -3
- package/dist/ui/settings-dialogs.js +20 -27
- package/dist/ui/settings-guests.js +14 -27
- package/dist/ui/settings-model.js +17 -12
- package/dist/ui/settings-quota-notice.js +100 -0
- package/dist/ui/settings-registry.js +4 -11
- package/dist/ui/settings-strings.js +4 -113
- package/dist/ui/settings-web-authority.js +13 -15
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-needs.js +1 -1
- package/dist/ui/shared/app-route.js +2 -6
- package/dist/ui/shared/app-shell.js +18 -23
- package/dist/ui/shared/app-store.js +2 -3
- package/dist/ui/shared/app-stream.js +1 -3
- package/dist/ui/shared/app.css +40 -1312
- package/dist/ui/shared/app.js +2 -5
- package/dist/ui/shared/header-tools.js +4 -6
- package/dist/ui/shared/instance-nav.js +7 -34
- package/dist/ui/shared/instance-switch.js +3 -4
- package/dist/ui/shared/loading.css +37 -0
- package/dist/ui/shared/panel-view.js +77 -4
- package/dist/ui/shared/signin.js +6 -39
- package/dist/ui/shared/tokens.css +0 -1
- package/dist/ui/shared/ui-dialog.js +2 -2
- package/dist/ui/shared/ui-menu.js +10 -30
- package/dist/ui/shared/ui-states.js +14 -3
- package/dist/ui/shared/usage-dialog.js +18 -1
- package/dist/ui/shared/vendor/vendor.json +2 -19
- package/dist/ui/shared/view-history.css +17 -0
- package/dist/ui/shared/view-history.js +438 -0
- package/dist/ui/shared/view-strings.js +16 -8
- package/dist/ui/signin.html +5 -2
- package/dist/unattended-install.d.ts +11 -2
- package/dist/unattended-install.js +39 -5
- package/dist/unattended-install.js.map +1 -1
- package/dist/usage/capacity.d.ts +69 -0
- package/dist/usage/capacity.js +119 -0
- package/dist/usage/capacity.js.map +1 -0
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +3 -0
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/profile-timeline.d.ts +16 -0
- package/dist/usage/profile-timeline.js +58 -0
- package/dist/usage/profile-timeline.js.map +1 -0
- package/dist/usage/providers.d.ts +5 -0
- package/dist/usage/providers.js +5 -0
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/quota-history.d.ts +43 -0
- package/dist/usage/quota-history.js +168 -0
- package/dist/usage/quota-history.js.map +1 -0
- package/dist/usage/quota-notices.d.ts +38 -0
- package/dist/usage/quota-notices.js +160 -0
- package/dist/usage/quota-notices.js.map +1 -0
- package/dist/usage/usage-api.d.ts +32 -0
- package/dist/usage/usage-api.js +96 -1
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +25 -1
- package/dist/usage-report.js +55 -4
- package/dist/usage-report.js.map +1 -1
- package/dist/usage-rollup.d.ts +6 -1
- package/dist/usage-rollup.js +16 -4
- package/dist/usage-rollup.js.map +1 -1
- package/dist/view-api.d.ts +16 -0
- package/dist/view-api.js +100 -16
- package/dist/view-api.js.map +1 -1
- package/dist/view-history.d.ts +84 -0
- package/dist/view-history.js +116 -0
- package/dist/view-history.js.map +1 -0
- package/dist/web-api.d.ts +6 -38
- package/dist/web-api.js +20 -255
- package/dist/web-api.js.map +1 -1
- package/dist/web-chat-history.d.ts +2 -19
- package/dist/web-chat-history.js +3 -72
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-only-fleet.d.ts +0 -20
- package/dist/web-only-fleet.js +0 -21
- package/dist/web-only-fleet.js.map +1 -1
- package/dist/web-session-authorization.d.ts +13 -2
- package/dist/web-session-authorization.js +10 -3
- package/dist/web-session-authorization.js.map +1 -1
- package/dist/web-session.d.ts +0 -7
- package/dist/web-session.js +0 -2
- package/dist/web-session.js.map +1 -1
- package/dist/web-shell-routes.d.ts +1 -4
- package/dist/web-shell-routes.js +2 -7
- package/dist/web-shell-routes.js.map +1 -1
- package/launcher/private-home.cjs +1 -1
- package/package.json +3 -9
- package/dist/agent-runtime-api.d.ts +0 -4
- package/dist/agent-runtime-api.js +0 -59
- package/dist/agent-runtime-api.js.map +0 -1
- package/dist/agent-runtime-change.d.ts +0 -74
- package/dist/agent-runtime-change.js +0 -102
- package/dist/agent-runtime-change.js.map +0 -1
- package/dist/backend/grok-model-cache.d.ts +0 -7
- package/dist/backend/grok-model-cache.js +0 -65
- package/dist/backend/grok-model-cache.js.map +0 -1
- package/dist/backend/native-pane.d.ts +0 -9
- package/dist/backend/native-pane.js +0 -59
- package/dist/backend/native-pane.js.map +0 -1
- package/dist/fleet-windows-runtime.d.ts +0 -97
- package/dist/fleet-windows-runtime.js +0 -449
- package/dist/fleet-windows-runtime.js.map +0 -1
- package/dist/general-binding.d.ts +0 -85
- package/dist/general-binding.js +0 -298
- package/dist/general-binding.js.map +0 -1
- package/dist/general-host-owner.d.ts +0 -8
- package/dist/general-host-owner.js +0 -26
- package/dist/general-host-owner.js.map +0 -1
- package/dist/general-role.d.ts +0 -5
- package/dist/general-role.js +0 -26
- package/dist/general-role.js.map +0 -1
- package/dist/local-pane-endpoint.d.ts +0 -46
- package/dist/local-pane-endpoint.js +0 -189
- package/dist/local-pane-endpoint.js.map +0 -1
- package/dist/local-pane-launcher.d.ts +0 -2
- package/dist/local-pane-launcher.js +0 -38
- package/dist/local-pane-launcher.js.map +0 -1
- package/dist/local-pane-stage.ps1 +0 -101
- package/dist/model-catalog-defaults.d.ts +0 -14
- package/dist/model-catalog-defaults.js +0 -20
- package/dist/model-catalog-defaults.js.map +0 -1
- package/dist/native-agent-admission.d.ts +0 -7
- package/dist/native-agent-admission.js +0 -26
- package/dist/native-agent-admission.js.map +0 -1
- package/dist/native-daemon-client.d.ts +0 -13
- package/dist/native-daemon-client.js +0 -28
- package/dist/native-daemon-client.js.map +0 -1
- package/dist/native-instance-api.d.ts +0 -14
- package/dist/native-instance-api.js +0 -205
- package/dist/native-instance-api.js.map +0 -1
- package/dist/native-instance-input.d.ts +0 -84
- package/dist/native-instance-input.js +0 -54
- package/dist/native-instance-input.js.map +0 -1
- package/dist/native-instance-registry.d.ts +0 -32
- package/dist/native-instance-registry.js +0 -105
- package/dist/native-instance-registry.js.map +0 -1
- package/dist/native-mcp.d.ts +0 -40
- package/dist/native-mcp.js +0 -278
- package/dist/native-mcp.js.map +0 -1
- package/dist/native-model-catalog.d.ts +0 -5
- package/dist/native-model-catalog.js +0 -76
- package/dist/native-model-catalog.js.map +0 -1
- package/dist/native-pane-crash-budget.d.ts +0 -20
- package/dist/native-pane-crash-budget.js +0 -60
- package/dist/native-pane-crash-budget.js.map +0 -1
- package/dist/native-pane-create.d.ts +0 -26
- package/dist/native-pane-create.js +0 -53
- package/dist/native-pane-create.js.map +0 -1
- package/dist/native-pane-lifecycle.d.ts +0 -65
- package/dist/native-pane-lifecycle.js +0 -230
- package/dist/native-pane-lifecycle.js.map +0 -1
- package/dist/native-pane-manager.d.ts +0 -59
- package/dist/native-pane-manager.js +0 -584
- package/dist/native-pane-manager.js.map +0 -1
- package/dist/native-pane-output-log.d.ts +0 -15
- package/dist/native-pane-output-log.js +0 -108
- package/dist/native-pane-output-log.js.map +0 -1
- package/dist/native-pane-reconciliation.d.ts +0 -4
- package/dist/native-pane-reconciliation.js +0 -40
- package/dist/native-pane-reconciliation.js.map +0 -1
- package/dist/native-pane-recovery.d.ts +0 -12
- package/dist/native-pane-recovery.js +0 -10
- package/dist/native-pane-recovery.js.map +0 -1
- package/dist/native-pane-tools.d.ts +0 -2
- package/dist/native-pane-tools.js +0 -14
- package/dist/native-pane-tools.js.map +0 -1
- package/dist/pane-port.d.ts +0 -118
- package/dist/pane-port.js +0 -2
- package/dist/pane-port.js.map +0 -1
- package/dist/runtime-api.d.ts +0 -8
- package/dist/runtime-api.js +0 -171
- package/dist/runtime-api.js.map +0 -1
- package/dist/runtime-assets/@xterm/addon-serialize/LICENSE +0 -21
- package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.js +0 -2
- package/dist/runtime-assets/@xterm/addon-serialize/lib/addon-serialize.mjs +0 -19
- package/dist/runtime-assets/@xterm/addon-serialize/package.json +0 -29
- package/dist/runtime-assets/@xterm/headless/LICENSE +0 -21
- package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.js +0 -2
- package/dist/runtime-assets/@xterm/headless/lib-headless/xterm-headless.mjs +0 -46
- package/dist/runtime-assets/@xterm/headless/package.json +0 -29
- package/dist/runtime-assets/node-pty/CONPTY-LICENSE +0 -21
- package/dist/runtime-assets/node-pty/CONPTY-NOTICE.md +0 -503
- package/dist/runtime-assets/node-pty/LICENSE +0 -69
- package/dist/runtime-assets/node-pty/lib/conpty_console_list_agent.js +0 -16
- package/dist/runtime-assets/node-pty/lib/eventEmitter2.js +0 -47
- package/dist/runtime-assets/node-pty/lib/index.js +0 -52
- package/dist/runtime-assets/node-pty/lib/interfaces.js +0 -7
- package/dist/runtime-assets/node-pty/lib/shared/conout.js +0 -11
- package/dist/runtime-assets/node-pty/lib/terminal.js +0 -190
- package/dist/runtime-assets/node-pty/lib/types.js +0 -7
- package/dist/runtime-assets/node-pty/lib/unixTerminal.js +0 -346
- package/dist/runtime-assets/node-pty/lib/utils.js +0 -39
- package/dist/runtime-assets/node-pty/lib/windowsConoutConnection.js +0 -125
- package/dist/runtime-assets/node-pty/lib/windowsPtyAgent.js +0 -320
- package/dist/runtime-assets/node-pty/lib/windowsTerminal.js +0 -199
- package/dist/runtime-assets/node-pty/lib/worker/conoutSocketWorker.js +0 -22
- package/dist/runtime-assets/node-pty/package.json +0 -64
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/dist/runtime-assets/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/dist/runtime-build-info.d.ts +0 -9
- package/dist/runtime-build-info.js +0 -57
- package/dist/runtime-build-info.js.map +0 -1
- package/dist/runtime-bundle.d.ts +0 -19
- package/dist/runtime-bundle.js +0 -156
- package/dist/runtime-bundle.js.map +0 -1
- package/dist/runtime-cli.d.ts +0 -7
- package/dist/runtime-cli.js +0 -152
- package/dist/runtime-cli.js.map +0 -1
- package/dist/runtime-client-store.d.ts +0 -68
- package/dist/runtime-client-store.js +0 -344
- package/dist/runtime-client-store.js.map +0 -1
- package/dist/runtime-client.d.ts +0 -112
- package/dist/runtime-client.js +0 -736
- package/dist/runtime-client.js.map +0 -1
- package/dist/runtime-connection.d.ts +0 -22
- package/dist/runtime-connection.js +0 -93
- package/dist/runtime-connection.js.map +0 -1
- package/dist/runtime-coordinator.d.ts +0 -91
- package/dist/runtime-coordinator.js +0 -911
- package/dist/runtime-coordinator.js.map +0 -1
- package/dist/runtime-general-protocol.d.ts +0 -22
- package/dist/runtime-general-protocol.js +0 -57
- package/dist/runtime-general-protocol.js.map +0 -1
- package/dist/runtime-general-workspace.d.ts +0 -17
- package/dist/runtime-general-workspace.js +0 -213
- package/dist/runtime-general-workspace.js.map +0 -1
- package/dist/runtime-pane-assets.d.ts +0 -17
- package/dist/runtime-pane-assets.js +0 -23
- package/dist/runtime-pane-assets.js.map +0 -1
- package/dist/runtime-pane-boot.d.ts +0 -9
- package/dist/runtime-pane-boot.js +0 -47
- package/dist/runtime-pane-boot.js.map +0 -1
- package/dist/runtime-pane-codex-index.d.ts +0 -1
- package/dist/runtime-pane-codex-index.js +0 -47
- package/dist/runtime-pane-codex-index.js.map +0 -1
- package/dist/runtime-pane-config.d.ts +0 -16
- package/dist/runtime-pane-config.js +0 -54
- package/dist/runtime-pane-config.js.map +0 -1
- package/dist/runtime-pane-host.d.ts +0 -44
- package/dist/runtime-pane-host.js +0 -424
- package/dist/runtime-pane-host.js.map +0 -1
- package/dist/runtime-pane-job-owner.d.ts +0 -1
- package/dist/runtime-pane-job-owner.js +0 -29
- package/dist/runtime-pane-job-owner.js.map +0 -1
- package/dist/runtime-pane-job.ps1 +0 -116
- package/dist/runtime-pane-link.d.ts +0 -40
- package/dist/runtime-pane-link.js +0 -246
- package/dist/runtime-pane-link.js.map +0 -1
- package/dist/runtime-pane-mcp-protocol.d.ts +0 -32
- package/dist/runtime-pane-mcp-protocol.js +0 -39
- package/dist/runtime-pane-mcp-protocol.js.map +0 -1
- package/dist/runtime-pane-mcp-relay.d.ts +0 -17
- package/dist/runtime-pane-mcp-relay.js +0 -70
- package/dist/runtime-pane-mcp-relay.js.map +0 -1
- package/dist/runtime-pane-mcp.d.ts +0 -51
- package/dist/runtime-pane-mcp.js +0 -150
- package/dist/runtime-pane-mcp.js.map +0 -1
- package/dist/runtime-pane-native.d.ts +0 -45
- package/dist/runtime-pane-native.js +0 -65
- package/dist/runtime-pane-native.js.map +0 -1
- package/dist/runtime-pane-output.d.ts +0 -19
- package/dist/runtime-pane-output.js +0 -53
- package/dist/runtime-pane-output.js.map +0 -1
- package/dist/runtime-pane-port.d.ts +0 -139
- package/dist/runtime-pane-port.js +0 -558
- package/dist/runtime-pane-port.js.map +0 -1
- package/dist/runtime-pane-private.d.ts +0 -14
- package/dist/runtime-pane-private.js +0 -51
- package/dist/runtime-pane-private.js.map +0 -1
- package/dist/runtime-pane-private.ps1 +0 -14
- package/dist/runtime-pane-process.d.ts +0 -4
- package/dist/runtime-pane-process.js +0 -108
- package/dist/runtime-pane-process.js.map +0 -1
- package/dist/runtime-pane-protocol.d.ts +0 -172
- package/dist/runtime-pane-protocol.js +0 -195
- package/dist/runtime-pane-protocol.js.map +0 -1
- package/dist/runtime-pane-screen.d.ts +0 -19
- package/dist/runtime-pane-screen.js +0 -76
- package/dist/runtime-pane-screen.js.map +0 -1
- package/dist/runtime-pane-service.d.ts +0 -11
- package/dist/runtime-pane-service.js +0 -221
- package/dist/runtime-pane-service.js.map +0 -1
- package/dist/runtime-pane-stdio-protocol.d.ts +0 -54
- package/dist/runtime-pane-stdio-protocol.js +0 -94
- package/dist/runtime-pane-stdio-protocol.js.map +0 -1
- package/dist/runtime-pane-stdio.d.ts +0 -3
- package/dist/runtime-pane-stdio.js +0 -123
- package/dist/runtime-pane-stdio.js.map +0 -1
- package/dist/runtime-pane-store.d.ts +0 -33
- package/dist/runtime-pane-store.js +0 -164
- package/dist/runtime-pane-store.js.map +0 -1
- package/dist/runtime-pane-transcript-protocol.d.ts +0 -43
- package/dist/runtime-pane-transcript-protocol.js +0 -58
- package/dist/runtime-pane-transcript-protocol.js.map +0 -1
- package/dist/runtime-pane-transcript.d.ts +0 -45
- package/dist/runtime-pane-transcript.js +0 -605
- package/dist/runtime-pane-transcript.js.map +0 -1
- package/dist/runtime-pane-worker.d.ts +0 -1
- package/dist/runtime-pane-worker.js +0 -154
- package/dist/runtime-pane-worker.js.map +0 -1
- package/dist/runtime-protocol.d.ts +0 -162
- package/dist/runtime-protocol.js +0 -37
- package/dist/runtime-protocol.js.map +0 -1
- package/dist/runtime-switches.d.ts +0 -79
- package/dist/runtime-switches.js +0 -90
- package/dist/runtime-switches.js.map +0 -1
- package/dist/runtime-transcript-delta-reader.d.ts +0 -23
- package/dist/runtime-transcript-delta-reader.js +0 -74
- package/dist/runtime-transcript-delta-reader.js.map +0 -1
- package/dist/runtime-transcript-source.d.ts +0 -36
- package/dist/runtime-transcript-source.js +0 -189
- package/dist/runtime-transcript-source.js.map +0 -1
- package/dist/runtime-windows-bridge.d.ts +0 -41
- package/dist/runtime-windows-bridge.js +0 -157
- package/dist/runtime-windows-bridge.js.map +0 -1
- package/dist/settings-route-lifetime.d.ts +0 -14
- package/dist/settings-route-lifetime.js +0 -48
- package/dist/settings-route-lifetime.js.map +0 -1
- package/dist/tmux-pane-host.d.ts +0 -26
- package/dist/tmux-pane-host.js +0 -25
- package/dist/tmux-pane-host.js.map +0 -1
- package/dist/transcript-needles.d.ts +0 -35
- package/dist/transcript-needles.js +0 -158
- package/dist/transcript-needles.js.map +0 -1
- package/dist/transcript-records.d.ts +0 -21
- package/dist/transcript-records.js +0 -140
- package/dist/transcript-records.js.map +0 -1
- package/dist/ui/agent-proposals.js +0 -90
- package/dist/ui/agent-runtime-settings.js +0 -67
- package/dist/ui/agent-runtime.js +0 -124
- package/dist/ui/cli-picker.js +0 -42
- package/dist/ui/general-location.js +0 -71
- package/dist/ui/native-instance-settings.js +0 -44
- package/dist/ui/native-pane-recovery.js +0 -45
- package/dist/ui/panel-runtimes.js +0 -334
- package/dist/ui/panel-windows-agent.js +0 -86
- package/dist/ui/panel-windows-cli.js +0 -179
- package/dist/ui/provider-marks.js +0 -83
- package/dist/ui/runtime-catalog.js +0 -55
- package/dist/ui/settings-agent-filters.js +0 -94
- package/dist/ui/settings-layout.js +0 -245
- package/dist/ui/settings-outside.js +0 -176
- package/dist/ui/settings-shortcuts.js +0 -65
- package/dist/ui/shared/machine-name.js +0 -13
- package/dist/ui/shared/qrcode.module.js +0 -2237
- package/dist/ui/shared/settings-width.js +0 -31
- package/dist/ui/shared/vendor/qrcode-generator.LICENSE +0 -27
- package/dist/ui/windows-agents-nav.js +0 -2
- package/dist/ui/windows-cli-catalog.js +0 -108
- package/dist/web-remote-access.d.ts +0 -152
- package/dist/web-remote-access.js +0 -368
- package/dist/web-remote-access.js.map +0 -1
- package/dist/windows-agents.d.ts +0 -126
- package/dist/windows-agents.js +0 -490
- package/dist/windows-agents.js.map +0 -1
- package/dist/windows-cli-api.d.ts +0 -23
- package/dist/windows-cli-api.js +0 -159
- package/dist/windows-cli-api.js.map +0 -1
- package/dist/windows-cli-providers.d.ts +0 -115
- package/dist/windows-cli-providers.js +0 -429
- package/dist/windows-cli-providers.js.map +0 -1
- package/dist/windows-cli-worker.d.ts +0 -59
- package/dist/windows-cli-worker.js +0 -479
- package/dist/windows-cli-worker.js.map +0 -1
- package/dist/windows-cli.d.ts +0 -116
- package/dist/windows-cli.js +0 -407
- package/dist/windows-cli.js.map +0 -1
- package/dist/windows-native-mcp.d.ts +0 -19
- package/dist/windows-native-mcp.js +0 -143
- package/dist/windows-native-mcp.js.map +0 -1
- package/dist/windows-pane-mcp.d.ts +0 -26
- package/dist/windows-pane-mcp.js +0 -187
- package/dist/windows-pane-mcp.js.map +0 -1
- package/templates/runtime-assets/conpty-LICENSE +0 -21
- package/templates/runtime-assets/conpty-NOTICE.md +0 -503
- package/templates/runtime-assets/local-pane-stage.ps1 +0 -101
- package/templates/runtime-assets/runtime-pane-job.ps1 +0 -116
- package/templates/runtime-assets/runtime-pane-private.ps1 +0 -14
- package/templates/runtime-assets/xterm-LICENSE +0 -21
package/dist/ui/shared/app.js
CHANGED
|
@@ -56,7 +56,8 @@ if (mode === "full") {
|
|
|
56
56
|
// A chat that loaded late catches up on what is open now; the shell shows that while it is not done, with Retry.
|
|
57
57
|
stream.on("hydration", (hydration) => appStore.set({ hydration }));
|
|
58
58
|
appStore.set({ retryHydration: () => stream.catchUp() });
|
|
59
|
-
|
|
59
|
+
appStore.set({ needsLoaded: false });
|
|
60
|
+
stream.on("needs", (d) => appStore.set({ needsLoaded: true, needs: Array.isArray(d && d.items) ? d.items : [] }));
|
|
60
61
|
// #1218: a panel's way to hear one stream event (the Log's steps_tick), unsubscribed by its lease.
|
|
61
62
|
appStore.set({ streamOn: (name, fn) => stream.on(name, fn) });
|
|
62
63
|
appStore.set({ connection: stream.connection() });
|
|
@@ -85,8 +86,6 @@ if (mode === "full") {
|
|
|
85
86
|
let chatLoads = 0;
|
|
86
87
|
panels.set("chat", { load: () => (chatLoads++ === 0 ? chatBoot : loadChat()).then((m) => m.ChatPanel) });
|
|
87
88
|
if (!guest) {
|
|
88
|
-
const loadWindowsAgent = retryable((a) => import(retryUrl("/ui/js/panel-windows-agent.js", a)));
|
|
89
|
-
panels.set("windows-agent", { load: () => loadWindowsAgent().then((m) => m.WindowsAgentPanel) });
|
|
90
89
|
panels.set("fleet", { load: () => loadFleet().then((m) => m.FleetPanel) });
|
|
91
90
|
panels.set("settings", { load: () => loadSettings().then((m) => m.SettingsPanel) });
|
|
92
91
|
// #2347: the restart banner's Restart now, in any panel — the Settings runner (behind the session) does it.
|
|
@@ -122,8 +121,6 @@ if (mode === "full") {
|
|
|
122
121
|
startNeedsNotifier({ open: (instance) => navigate(chatPath(instance)) });
|
|
123
122
|
// #2233: a backend sign-in running anywhere is shown on every admin page (the module lives behind the session gate).
|
|
124
123
|
import("/ui/js/backend-signin.js").then((m) => m.installSignIn(), () => {});
|
|
125
|
-
// alpha.2 (M-2300): an agent's Windows request waiting for a web-only fleet's owner — counted in Needs you everywhere.
|
|
126
|
-
import("/ui/js/agent-proposals.js").then((m) => m.installProposals(), () => {});
|
|
127
124
|
}
|
|
128
125
|
// #1665: this device's first upload of its own choices (once), then another device's changes at each status frame.
|
|
129
126
|
// A guest's page (#2855) uploads and saves only its own keys (prefsWritable(key)); another device's changes reach it at
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// Fleet read (#1300: no style attribute). View's terminal multiplies its fitted size by VIEW_SCALE, as its density did.
|
|
8
8
|
import { html, useEffect, useState } from "./app-html.js";
|
|
9
9
|
import { t } from "./app-i18n.js";
|
|
10
|
-
import {
|
|
10
|
+
import { createStore, useStore } from "./app-store.js";
|
|
11
11
|
import { Icon } from "./ui-icons.js";
|
|
12
12
|
import { UsageBody, UsageCompactToggle, UsageDialog } from "./usage-dialog.js";
|
|
13
13
|
|
|
@@ -124,9 +124,7 @@ export function useRailWidth() {
|
|
|
124
124
|
export function UsageRail({ route }) {
|
|
125
125
|
const wide = useRailWidth();
|
|
126
126
|
const { open } = useStore(usageRailStore);
|
|
127
|
-
|
|
128
|
-
const instance = instances.find(item => item.name === route?.instance);
|
|
129
|
-
if (!wide || !open || !route || !RAIL_PANELS.includes(route.panel) || !usageOffered() || instance?.capabilities?.usage === false) return null;
|
|
127
|
+
if (!wide || !open || !route || !RAIL_PANELS.includes(route.panel) || !usageOffered()) return null;
|
|
130
128
|
return html`<aside data-trust="usage" class="u-rail" aria-label=${t("view.usage.title_plain")}>
|
|
131
129
|
<div class="u-rail-head"><h2>${t("view.usage.title")}</h2><${UsageCompactToggle} />
|
|
132
130
|
<button type="button" class="icon-btn" onClick=${() => setUsageRail(false)} aria-label=${t("app.usageHide")} title=${t("app.usageHide")}><${Icon} name="close" size=${16} /></button></div>
|
|
@@ -156,8 +154,8 @@ export function UsageButton({ navKey }) {
|
|
|
156
154
|
}
|
|
157
155
|
|
|
158
156
|
/** The shared controls, in the one order every page uses. `navKey`: the page's navigation (the usage dialog's owner). */
|
|
159
|
-
export function HeaderTools({ view = false, navKey
|
|
160
|
-
return html`<${TextSizeButton} view=${view}
|
|
157
|
+
export function HeaderTools({ view = false, navKey }) {
|
|
158
|
+
return html`<${TextSizeButton} view=${view} /><${UsageButton} navKey=${navKey} />`;
|
|
161
159
|
}
|
|
162
160
|
/** Where a page with no control of its own after the shared ones (Log) keeps the room Chat's ⋯ takes: the same box on every tab. */
|
|
163
161
|
export function HeaderSlot() {
|
|
@@ -18,7 +18,6 @@ import { viewStore } from "./view-roster-store.js";
|
|
|
18
18
|
import { onPrefsChanged, prefInForce, prefsWritable, savePref } from "./app-prefs.js";
|
|
19
19
|
import "./view-strings.js";
|
|
20
20
|
import { themesShown, themesStore } from "./app-themes.js";
|
|
21
|
-
import { machineName } from "./machine-name.js";
|
|
22
21
|
import { identityClasses, identityOf, paintIdentity, useIdentityColors } from "./identity-color.js";
|
|
23
22
|
|
|
24
23
|
/** view.* text with named values. */
|
|
@@ -80,14 +79,6 @@ export function modelText(it, raw = it && it.model) {
|
|
|
80
79
|
}
|
|
81
80
|
const BACKEND_LABELS = { "claude-code": "Claude Code", "kiro-cli": "Kiro CLI", codex: "Codex", grok: "Grok Build", antigravity: "Antigravity", opencode: "OpenCode" };
|
|
82
81
|
export function backendLabel(backend) { return BACKEND_LABELS[backend] || backend || "Unknown"; }
|
|
83
|
-
export function runtimeLabel(runtime) { return runtime === "windows" ? "Windows" : runtime === "wsl" ? "WSL / Linux" : runtime || ""; }
|
|
84
|
-
/** Missing capabilities preserve the existing Linux UI; native runtimes expose only implemented controls. */
|
|
85
|
-
export function supportsInstanceFeature(instance, feature) {
|
|
86
|
-
const key = feature === "view" ? "terminal" : feature;
|
|
87
|
-
if (typeof instance?.capabilities?.[key] === "boolean") return instance.capabilities[key];
|
|
88
|
-
if (feature === "log" && typeof instance?.capabilities?.terminal === "boolean") return instance.capabilities.terminal;
|
|
89
|
-
return instance?.runtime !== "windows" || !["terminal","view","log","details","attachments","commands","effort","send_while_busy"].includes(feature);
|
|
90
|
-
}
|
|
91
82
|
export const KNOWN_BACKENDS = new Set(Object.keys(BACKEND_LABELS));
|
|
92
83
|
export const STATUS_KEYS = { running: "statusRunning", paused: "statusPaused", stopped: "statusStopped", crashed: "statusCrashed" };
|
|
93
84
|
|
|
@@ -106,7 +97,7 @@ export function normalizeFilter(query) { return String(query == null ? "" : quer
|
|
|
106
97
|
/** Case-insensitive substring on name (incl. display name), model and backend. */
|
|
107
98
|
export function instanceMatchesFilter(it, needle, labelOf) {
|
|
108
99
|
if (!needle) return true;
|
|
109
|
-
const fields = [nameOf(it), it.display_name, it.model, it.backend,
|
|
100
|
+
const fields = [nameOf(it), it.display_name, it.model, it.backend, labelOf ? labelOf(it.backend) : null];
|
|
110
101
|
return fields.some((value) => typeof value === "string" && value.toLowerCase().includes(needle));
|
|
111
102
|
}
|
|
112
103
|
/**
|
|
@@ -145,9 +136,6 @@ export function instanceTooltip(it) {
|
|
|
145
136
|
if (it.display_name && it.display_name !== name) lines.push(it.display_name, `(${name})`);
|
|
146
137
|
else lines.push(name);
|
|
147
138
|
lines.push(line("tooltipBackend", backendLabel(it.backend)));
|
|
148
|
-
if (it.runtime) lines.push(`Runtime: ${runtimeLabel(it.runtime)}`);
|
|
149
|
-
if (it.machine_id) lines.push(line("tooltipMachine",machineName(it.machine_id,it.machine_name)));
|
|
150
|
-
if (it.machine_id && it.machine_status !== "online") lines.push(tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline"));
|
|
151
139
|
const src = (s) => (s === "instance" || s === "classic" ? tn("srcConfigured") : s === "fleet-default" ? tn("srcFleetDefault") : "");
|
|
152
140
|
lines.push(line("tooltipModel", (modelText(it) || tn("tooltipUnavailable")) + src(it.model_source)));
|
|
153
141
|
lines.push(line("tooltipStatus", status));
|
|
@@ -295,8 +283,6 @@ function writeFacetsOpen(open) { try { localStorage.setItem(FACETS_KEY, JSON.str
|
|
|
295
283
|
|
|
296
284
|
/** The Favorites group's key among the tag groups: no tag can be it (a group name is never a control character). */
|
|
297
285
|
const FAV_GROUP = "\u0000favorites";
|
|
298
|
-
/** #3008 G2: a web-only fleet's General (its status row says `general: true`), pinned first under its own head. */
|
|
299
|
-
const GENERAL_GROUP = "\u0000general";
|
|
300
286
|
/** #1936: the open instance, pinned on top while a filter is on. */
|
|
301
287
|
const PINNED_GROUP = "\u0000pinned";
|
|
302
288
|
function persistOrder(groupNames, instByGroup) {
|
|
@@ -504,11 +490,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
504
490
|
const [editing, setEditing] = useState(false);
|
|
505
491
|
// Where a row goes: the view the page is in (#1523 §3.1). View → View; Details → Details; everywhere else, a Fleet tab
|
|
506
492
|
// included (#1917: the user's call, replacing Q4 = A), → Chat. The anonymous reader only ever has View.
|
|
507
|
-
const
|
|
493
|
+
const rowPath = viewOnly || (route && route.panel === "view") ? viewPath
|
|
508
494
|
: route && route.panel === "log" ? logPath // #1218: Log → Log
|
|
509
495
|
: route && route.panel === "details" ? detailsPath : chatPath;
|
|
510
|
-
const rowPath = (name) => byName.get(name)?.runtime === "windows" && ["view", "log", "details"].includes(route?.panel)
|
|
511
|
-
? chatPath(name) : panelPath(name);
|
|
512
496
|
const active = route && (route.panel === "chat" || route.panel === "view" || route.panel === "log" || route.panel === "details") ? route.instance : null;
|
|
513
497
|
const own = (map, name) => Object.prototype.hasOwnProperty.call(map, name);
|
|
514
498
|
const byName = new Map(items.map((it) => [nameOf(it), it]));
|
|
@@ -518,10 +502,7 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
518
502
|
// their order. Changing them: a signed-in page that may write preferences (not the public link, not the anonymous
|
|
519
503
|
// reader — they still see the list).
|
|
520
504
|
const known = new Set(byName.keys());
|
|
521
|
-
|
|
522
|
-
const general = items.find((it) => it && it.general === true);
|
|
523
|
-
const generalName = general ? nameOf(general) : null;
|
|
524
|
-
const favs = nav.favorites.filter((n) => known.has(n) && n !== generalName);
|
|
505
|
+
const favs = nav.favorites.filter((n) => known.has(n));
|
|
525
506
|
const favSet = new Set(favs);
|
|
526
507
|
const canStar = !viewOnly && prefsWritable("nav.favorites");
|
|
527
508
|
// #1920: a guest's list is not reordered (the order is the host's). #2855: it stars, sorts and filters as its own
|
|
@@ -539,15 +520,14 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
539
520
|
let shownGroups, shownInsts;
|
|
540
521
|
if (recent) {
|
|
541
522
|
const sortRecent = byRecentReply(ageOf);
|
|
542
|
-
const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n)
|
|
523
|
+
const rest = groupNames.flatMap((g) => instByGroup.get(g) || []).filter((n) => !favSet.has(n)).sort(sortRecent);
|
|
543
524
|
shownGroups = [...(favs.length ? [FAV_GROUP] : []), ...(rest.length ? [RECENT_GROUP] : [])];
|
|
544
525
|
shownInsts = new Map([[FAV_GROUP, favsSorted ? [...favs].sort(sortRecent) : favs], [RECENT_GROUP, rest]]);
|
|
545
526
|
} else {
|
|
546
527
|
shownGroups = favs.length ? [FAV_GROUP, ...groupNames] : groupNames;
|
|
547
|
-
shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n)
|
|
528
|
+
shownInsts = new Map([...instByGroup].map(([g, names]) => [g, names.filter((n) => !favSet.has(n))]));
|
|
548
529
|
if (favs.length) shownInsts.set(FAV_GROUP, favs);
|
|
549
530
|
}
|
|
550
|
-
if (generalName) { shownGroups = [GENERAL_GROUP, ...shownGroups]; shownInsts.set(GENERAL_GROUP, [generalName]); }
|
|
551
531
|
const f = nav.filter;
|
|
552
532
|
const shown = filterSidebar(shownGroups, shownInsts, byName, f.q, backendLabel, { status: f.status, cli: f.cli, statusOf: facetOf });
|
|
553
533
|
// #1936: while a filter is on, the instance you have open stays on top, pinned and marked "Current", whether or not
|
|
@@ -609,9 +589,7 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
609
589
|
const row = (name, g, i, count) => {
|
|
610
590
|
const it = byName.get(name);
|
|
611
591
|
// #1722: both names, the preferred one first; one line when there is no other.
|
|
612
|
-
const
|
|
613
|
-
const label = it.runtime === "windows" ? it.display_name || preferred.primary : preferred.primary;
|
|
614
|
-
const secondary = it.runtime === "windows" ? backendLabel(it.backend) : preferred.secondary;
|
|
592
|
+
const { primary: label, secondary } = namesOf(it, names.primary);
|
|
615
593
|
const facet = facetOf(name);
|
|
616
594
|
const waiting = own(awaiting, name) ? awaiting[name] : null;
|
|
617
595
|
const on = name === active;
|
|
@@ -628,10 +606,9 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
628
606
|
aria-current=${on ? "page" : undefined} onClick=${onPick} ...${fav ? {} : dragProps({ type: "instance", name, group: g })}>
|
|
629
607
|
<${InstanceAvatar} it=${it} state=${dotState(it, own(exec, name) ? exec[name] : null, waiting)} cli=${true} />
|
|
630
608
|
<span class="inst-text"><span class="inst-line"><span class="inst-name" title=${label}>${label}</span>
|
|
631
|
-
<span class="v-meta">${it.
|
|
609
|
+
<span class="v-meta">${it.context_pct != null ? `${Math.round(it.context_pct)}%` : ""}</span></span>
|
|
632
610
|
${two ? html`<span class="inst-line inst-line2"><span class="inst-alt" title=${secondary || undefined}>${secondary || ""}</span>
|
|
633
611
|
${mins != null ? html`<span class=${`inst-when${fade > 0 ? " fresh" : ""}`} title=${tn("replyTitle", { time: new Date(Date.parse(it.last_reply)).toLocaleString() })}>${replyText(mins)}</span>` : null}</span>` : null}
|
|
634
|
-
${it.machine_id ? html`<span class=${`inst-machine${it.machine_status !== "online" ? " offline" : ""}`} title=${tn("tooltipMachine",{value:machineName(it.machine_id,it.machine_name)})}><span class="inst-machine-name">${machineName(it.machine_id,it.machine_name)}</span>${it.machine_status !== "online" ? html`<span class="inst-machine-status">${tn(it.machine_status === "revoked" ? "machineRevoked" : "machineOffline")}</span>` : null}</span>` : null}
|
|
635
612
|
${facet === "needs" ? html`<span class="inst-sub"><span class="badge-await" title=${waiting || t("app.approxNote")}>${t("app.needsYou")}</span></span>` : null}
|
|
636
613
|
<span class="sr-only">${tn("tooltipBackend", { value: backendLabel(it.backend) })}</span></span>
|
|
637
614
|
</a>${fav && editing && canStar ? html`<button type="button" class="icon-btn inst-move" aria-label=${tn("favUp", { name: label })}
|
|
@@ -662,10 +639,6 @@ export function InstanceNav({ route, items, loaded = true, exec = {}, awaiting =
|
|
|
662
639
|
if (g === RECENT_GROUP) return html`<div key=${g} class="v-group v-recent" role="group" aria-label=${tn("recentOthers")}>
|
|
663
640
|
<div class="v-group-head recent-head"><${Icon} name="clock" size=${14} /><span class="grow">${tn("recentOthers")}</span><span class="count">${names.length}</span></div>
|
|
664
641
|
<ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
|
|
665
|
-
// #3008 G2: the General — always open, first, not dragged or starred into another place.
|
|
666
|
-
if (g === GENERAL_GROUP) return html`<div key=${g} class="v-group v-general" role="group" aria-label=${tn("generalGroup")}>
|
|
667
|
-
<div class="v-group-head general-head"><span class="grow">${tn("generalGroup")}</span></div>
|
|
668
|
-
<ul class="inst-list">${names.map((name, i) => row(name, g, i, names.length))}</ul></div>`;
|
|
669
642
|
// #1664: Favorites — always open, not dragged (↑ ↓ in Edit), named in the page's language.
|
|
670
643
|
if (g === FAV_GROUP) return html`<div key=${g} class="v-group v-fav" role="group" aria-label=${tn("favorites")}>
|
|
671
644
|
<div class="v-group-head fav-head"><${Icon} name="star" size=${14} cls="fav-mark" /><span class="grow">${tn("favorites")}</span><span class="count">${names.length}</span></div>
|
|
@@ -7,20 +7,19 @@ import { html } from "./app-html.js";
|
|
|
7
7
|
import { openSearch } from "./app-shell.js";
|
|
8
8
|
import { t } from "./app-i18n.js";
|
|
9
9
|
import { chatPath, detailsPath, logPath, viewPath } from "./app-route.js";
|
|
10
|
-
import { supportsInstanceFeature } from "./instance-nav.js";
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* current: "chat" | "view" | "log" | "details". #1218: Log sits between View and Details. `data-label`: each tab is as
|
|
14
13
|
* wide as its label in the current tab's weight (app.css), so the bar keeps its size whichever tab is current.
|
|
15
14
|
*/
|
|
16
|
-
export function InstanceSwitch({ name, current, guest = false
|
|
15
|
+
export function InstanceSwitch({ name, current, guest = false }) {
|
|
17
16
|
const seg = (key, href, label) => html`<a key=${key} class=${`seg-item${current === key ? " active" : ""}`} href=${href}
|
|
18
17
|
aria-current=${current === key ? "page" : undefined} data-label=${label}>${label}</a>`;
|
|
19
18
|
if (guest) return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
|
|
20
|
-
${seg("chat", chatPath(name), t("app.chat"))}${
|
|
19
|
+
${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}<button key="search" type="button" class="seg-item"
|
|
21
20
|
data-label=${t("app.search")} onClick=${() => openSearch({ instance: name })}>${t("app.search")}</button>
|
|
22
21
|
</nav>`;
|
|
23
22
|
return html`<nav class="inst-switch seg" aria-label=${t("app.instanceViews", name)}>
|
|
24
|
-
${seg("chat", chatPath(name), t("app.chat"))}${
|
|
23
|
+
${seg("chat", chatPath(name), t("app.chat"))}${seg("view", viewPath(name), t("app.view"))}${seg("log", logPath(name), t("app.log"))}${seg("details", detailsPath(name), t("app.details"))}
|
|
25
24
|
</nav>`;
|
|
26
25
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/* The shared Skeleton's calm content shapes, including before the app's modules arrive. No shimmer or spinner. */
|
|
2
|
+
.skeleton { box-sizing: border-box; width: 100%; min-width: 0; }
|
|
3
|
+
.skeleton > [aria-hidden] { display: flex; flex-direction: column; gap: 14px; width: 100%; }
|
|
4
|
+
.skeleton .sk-line { height: 14px; flex-shrink: 0; background: var(--surface-2, #e8e8eb); border-radius: 5px; }
|
|
5
|
+
.sk-row { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 8px 0; }
|
|
6
|
+
.sk-row .sk-thumb { width: 36px; height: 36px; border-radius: 9px; }
|
|
7
|
+
.sk-row .sk-copy { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 9px; }
|
|
8
|
+
.sk-row .sk-copy .sk-line { width: 76%; height: 12px; }
|
|
9
|
+
.sk-row .sk-copy .sk-line + .sk-line { width: 51%; height: 10px; }
|
|
10
|
+
.sk-row .sk-pill { width: 52px; height: 22px; border-radius: 99px; }
|
|
11
|
+
.sk-cards .sk-row { min-height: 104px; border-bottom: 1px solid var(--border, #ddd); }
|
|
12
|
+
.sk-inline { max-width: 140px; min-width: 90px; padding: 0; margin: 0; }
|
|
13
|
+
.s-profile { position: relative; }
|
|
14
|
+
.s-profile-fields { display: flex; flex-direction: column; gap: var(--s-3, 12px); }
|
|
15
|
+
.sk-reserve { visibility: hidden; pointer-events: none; }
|
|
16
|
+
.sk-profile-cover { position: absolute; inset: 52px 16px 16px; }
|
|
17
|
+
.s-pref-profile-fields > .sk-profile-cover { inset: 0; }
|
|
18
|
+
.sk-profile-cover .skeleton { padding: 0; margin: 0; max-width: none; }
|
|
19
|
+
.sk-form .sk-line:nth-child(3) { width: 100%; height: 40px; }
|
|
20
|
+
.sk-form .sk-line:nth-child(4) { width: 48%; height: 32px; border-radius: 99px; }
|
|
21
|
+
.sk-boot { display: flex; height: 100dvh; background: var(--bg, #f6f6f8); }
|
|
22
|
+
.sk-boot-side { width: var(--sidebar-w, 248px); padding: 28px 20px; border-right: 1px solid var(--border, #ddd); }
|
|
23
|
+
.sk-boot-main { flex: 1; min-width: 0; }
|
|
24
|
+
.sk-boot-head { height: 64px; border-bottom: 1px solid var(--border, #ddd); }
|
|
25
|
+
.sk-boot-head .sk-line { width: 160px; }
|
|
26
|
+
.sk-boot .skeleton { margin: 0; max-width: 760px; opacity: 1; animation: none; }
|
|
27
|
+
.sk-boot .sk-line { height: 14px; background: var(--surface-2, #e8e8eb); }
|
|
28
|
+
.signin-card { position: relative; }
|
|
29
|
+
/* Reserve the real, translated form's size while the session is checked; hidden fields cannot be focused. */
|
|
30
|
+
.signin-card:has(#checking:not([hidden])) #form[hidden] { display: block !important; visibility: hidden; pointer-events: none; }
|
|
31
|
+
.sk-signin { position: absolute; inset: 72px 24px 28px; width: auto; padding: 0; margin: 0; max-width: none; }
|
|
32
|
+
.sk-signin > [aria-hidden] { gap: 18px; }
|
|
33
|
+
.sk-signin .sk-line:first-child { width: 70%; height: 26px; }
|
|
34
|
+
.sk-signin .sk-line:nth-child(3) { width: 100%; height: 48px; }
|
|
35
|
+
.sk-signin .sk-line:nth-child(4) { width: 100%; height: 42px; border-radius: 99px; }
|
|
36
|
+
@media (max-width: 899px) { .sk-boot-side { display: none; } }
|
|
37
|
+
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; opacity: 1; } }
|
|
@@ -282,6 +282,13 @@ const REDRAWS_IN_PLACE = new Set(["grok"]);
|
|
|
282
282
|
const FULL_SCREEN = new Set(["claude-code", "opencode", "grok"]); // agy: its chat UI unverified — found by the read
|
|
283
283
|
/** The full-screen CLIs whose earlier output the Log tab shows (it reads their transcript: log-service.ts). */
|
|
284
284
|
const LOG_HAS_HISTORY = new Set(["claude-code"]);
|
|
285
|
+
/**
|
|
286
|
+
* Claude history in the View (view-history.js): the full-screen CLIs whose View shows their earlier conversation from
|
|
287
|
+
* their transcript, above the live screen. A server without it (an older one) leaves them as before: no scrollback.
|
|
288
|
+
*/
|
|
289
|
+
const TRANSCRIPT_HISTORY = new Set(["claude-code"]);
|
|
290
|
+
/** How near the top (px) a history being read asks for the page before it. */
|
|
291
|
+
const OLDER_AT_PX = 48;
|
|
285
292
|
/**
|
|
286
293
|
* M-2267 option (2), the leader's safe default: where a full-screen CLI's earlier output is — its Log tab (or that the
|
|
287
294
|
* Log tab is off, and where to turn it on). Only for whom the Log tab is (a signed-in session on the full app; never a
|
|
@@ -304,8 +311,11 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
304
311
|
const [newBelow, setNewBelow] = useState(false);
|
|
305
312
|
const [historyNote, setHistoryNoteState] = useState(null);
|
|
306
313
|
// A CLI found to keep no scrollback (full screen): nothing is offered or read again for it; the note says why, briefly.
|
|
307
|
-
const
|
|
308
|
-
const
|
|
314
|
+
const keepsNone = FULL_SCREEN.has(backend) && !TRANSCRIPT_HISTORY.has(backend);
|
|
315
|
+
const [noScrollback, setNoScrollback] = useState(keepsNone);
|
|
316
|
+
const noScrollbackRef = useRef(keepsNone);
|
|
317
|
+
// Claude history in the View: the history shown while reading (view-history.js's createHistory), or null.
|
|
318
|
+
const transcript = useRef(null);
|
|
309
319
|
const logLink = logLinkFor(name, backend, signedIn);
|
|
310
320
|
const noteTimer = useRef(null);
|
|
311
321
|
const setHistoryNote = (note, brief = false) => {
|
|
@@ -402,6 +412,7 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
402
412
|
// The person asked for what scrolled off: one bounded read, then reading (or why there is nothing to read).
|
|
403
413
|
const loadEarlier = useRef(null);
|
|
404
414
|
const follow = useRef(null);
|
|
415
|
+
const olderPage = useRef(null);
|
|
405
416
|
useEffect(() => {
|
|
406
417
|
const reads = readStream(lease);
|
|
407
418
|
const refresh = async () => {
|
|
@@ -439,6 +450,7 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
439
450
|
const from = modeRef.current;
|
|
440
451
|
if (from !== "follow" && !(from === "reading" && !screenAt.current.history)) return;
|
|
441
452
|
if (noScrollbackRef.current) { setHistoryNote(tn("noEarlier"), true); return; } // known: nothing to read
|
|
453
|
+
if (TRANSCRIPT_HISTORY.has(backend)) { await loadTranscript(from); return; }
|
|
442
454
|
const box0 = term.current;
|
|
443
455
|
// Where the person is, measured from the end: the screen's lines stay where they are under the scrollback added.
|
|
444
456
|
const fromEnd = box0 ? box0.scrollHeight - box0.scrollTop : 0;
|
|
@@ -477,8 +489,65 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
477
489
|
}
|
|
478
490
|
} catch { if (lease.current()) { back(); setHistoryNote(tn("earlierFailed"), true); } }
|
|
479
491
|
};
|
|
492
|
+
/**
|
|
493
|
+
* Claude history in the View: the conversation before the live screen, from the transcript (the renderer is its own
|
|
494
|
+
* lazy module), drawn above the screen as it is now — then reading, as for a scrollback. Older pages come as the
|
|
495
|
+
* person nears the top. A server without it: this CLI keeps no scrollback, as before.
|
|
496
|
+
*/
|
|
497
|
+
const loadTranscript = async (from) => {
|
|
498
|
+
const back = () => { setMode(from); if (from === "follow") toBottom(); };
|
|
499
|
+
const screen = screenAt.current.drawn == null ? "" : screenAt.current.drawn;
|
|
500
|
+
setMode("loading"); setHistoryNote(tn("loadingEarlier"));
|
|
501
|
+
try {
|
|
502
|
+
const mod = await import("./view-history.js");
|
|
503
|
+
if (!lease.current() || modeRef.current !== "loading" || !pre.current) return;
|
|
504
|
+
let h = null;
|
|
505
|
+
h = mod.createHistory({ name, fetch: (u) => lease.fetch(u), alive: () => lease.current() && transcript.current === h,
|
|
506
|
+
doc: document, font: getComputedStyle(pre.current).fontFamily, cols: grid.current.cols });
|
|
507
|
+
transcript.current = h;
|
|
508
|
+
const got = await h.first(screen);
|
|
509
|
+
if (!lease.current() || modeRef.current !== "loading" || !pre.current || transcript.current !== h) return;
|
|
510
|
+
if (got.kind !== "ok") {
|
|
511
|
+
transcript.current = null;
|
|
512
|
+
if (got.kind === "unsupported") { noScrollbackRef.current = true; setNoScrollback(true); back(); setHistoryNote(tn("noEarlier"), true); return; }
|
|
513
|
+
back();
|
|
514
|
+
setHistoryNote(got.kind === "empty" ? tn("nothingEarlier") : got.status === 429 ? null : tn("earlierFailed"), true);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
screenAt.current.reading = screen; screenAt.current.history = true;
|
|
518
|
+
setNewBelow(screenAt.current.latest != null && !sameScreen(screen, screenAt.current.latest));
|
|
519
|
+
setMode("reading"); setHistoryNote(null);
|
|
520
|
+
draw(screen); // the screen as it is (the one frame write), then the history above it
|
|
521
|
+
pre.current.insertBefore(h.root, pre.current.firstChild);
|
|
522
|
+
fit();
|
|
523
|
+
const box = term.current;
|
|
524
|
+
if (box) {
|
|
525
|
+
const px = parseFloat(getComputedStyle(pre.current).fontSize);
|
|
526
|
+
const lineH = Number.isFinite(px) && px > 0 ? px * 1.2 : 16;
|
|
527
|
+
// The history's last lines and the divider right above the screen.
|
|
528
|
+
box.scrollTop = Math.max(0, box.scrollHeight - box.clientHeight - lineH * 3);
|
|
529
|
+
}
|
|
530
|
+
} catch { if (lease.current() && modeRef.current === "loading") { transcript.current = null; back(); setHistoryNote(tn("earlierFailed"), true); } }
|
|
531
|
+
};
|
|
532
|
+
/** The page before the history shown, above it — where the person is stays where it is. */
|
|
533
|
+
let olderBusy = false;
|
|
534
|
+
olderPage.current = async () => {
|
|
535
|
+
const h = transcript.current, box = term.current;
|
|
536
|
+
if (olderBusy || !h || !box || modeRef.current !== "reading" || !screenAt.current.history) return;
|
|
537
|
+
olderBusy = true;
|
|
538
|
+
const fromEnd = box.scrollHeight - box.scrollTop;
|
|
539
|
+
const capped = !h.hasOlder();
|
|
540
|
+
if (!capped) setHistoryNote(tn("loadingEarlier"));
|
|
541
|
+
try {
|
|
542
|
+
const got = await h.older();
|
|
543
|
+
if (!lease.current() || transcript.current !== h) return;
|
|
544
|
+
box.scrollTop = Math.max(0, box.scrollHeight - fromEnd);
|
|
545
|
+
if (!capped) setHistoryNote(got.kind === "failed" ? tn("earlierFailed") : null, got.kind === "failed");
|
|
546
|
+
} finally { olderBusy = false; }
|
|
547
|
+
};
|
|
480
548
|
follow.current = () => {
|
|
481
549
|
if (modeRef.current === "follow") return;
|
|
550
|
+
transcript.current = null;
|
|
482
551
|
setMode("follow"); setNewBelow(false); setHistoryNote(null); screenAt.current.history = false;
|
|
483
552
|
const latest = screenAt.current.latest;
|
|
484
553
|
if (latest != null && pre.current) { draw(latest); fit(); }
|
|
@@ -501,7 +570,9 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
501
570
|
// Asking for the earlier output: from following, or from reading the screen as it was — at the top.
|
|
502
571
|
const mayLoad = () => (modeRef.current === "follow" || (modeRef.current === "reading" && !screenAt.current.history)) && box.scrollTop <= 0;
|
|
503
572
|
const gesture = () => { gestureAt.current = performance.now(); };
|
|
504
|
-
|
|
573
|
+
// Claude's history being read, at (or near) its top: the page before it.
|
|
574
|
+
const nearTop = () => modeRef.current === "reading" && screenAt.current.history && transcript.current && box.scrollTop <= OLDER_AT_PX;
|
|
575
|
+
lease.on(box, "wheel", (e) => { gesture(); if (e.deltaY < 0 && mayLoad()) loadEarlier.current(); else if (e.deltaY < 0 && nearTop()) olderPage.current(); }, { passive: true });
|
|
505
576
|
let touchY = null;
|
|
506
577
|
lease.on(box, "touchstart", (e) => { gesture(); touchY = e.touches && e.touches[0] ? e.touches[0].clientY : null; }, { passive: true });
|
|
507
578
|
lease.on(box, "touchmove", (e) => {
|
|
@@ -509,15 +580,17 @@ function Terminal({ name, lease, density, every = 800, backend = "", signedIn =
|
|
|
509
580
|
const y = e.touches && e.touches[0] ? e.touches[0].clientY : null;
|
|
510
581
|
if (touchY == null || y == null) return;
|
|
511
582
|
if (y - touchY > 24 && mayLoad()) { touchY = null; loadEarlier.current(); }
|
|
583
|
+
else if (y - touchY > 24 && nearTop()) { touchY = null; olderPage.current(); }
|
|
512
584
|
}, { passive: true });
|
|
513
585
|
lease.on(box, "pointerdown", gesture, { passive: true }); // the scrollbar, dragged
|
|
514
586
|
lease.on(box, "keydown", (e) => {
|
|
515
587
|
gesture();
|
|
516
588
|
if ((e.key === "PageUp" || e.key === "ArrowUp" || e.key === "Home") && mayLoad()) { e.preventDefault(); loadEarlier.current(); }
|
|
589
|
+
else if ((e.key === "PageUp" || e.key === "ArrowUp" || e.key === "Home") && nearTop()) olderPage.current();
|
|
517
590
|
else if (modeRef.current === "reading" && e.key === "End") { e.preventDefault(); follow.current(); }
|
|
518
591
|
});
|
|
519
592
|
lease.on(box, "scroll", () => {
|
|
520
|
-
if (modeRef.current === "reading") { if (atBottom()) follow.current(); return; }
|
|
593
|
+
if (modeRef.current === "reading") { if (atBottom()) follow.current(); else if (nearTop()) olderPage.current(); return; }
|
|
521
594
|
// #2969 review (Prism P2): a screen taller than its box (a larger Aa), moved up from the bottom by the person:
|
|
522
595
|
// reading what is on it — the refresh no longer pulls them back down.
|
|
523
596
|
if (modeRef.current === "follow" && recentGesture() && !atBottom()) startReading(screenAt.current.drawn, false);
|
package/dist/ui/shared/signin.js
CHANGED
|
@@ -27,12 +27,6 @@
|
|
|
27
27
|
hint_web: "On the AgEnD computer, run agend web --code to get a sign-in code.",
|
|
28
28
|
refused_web: "The code is invalid or no longer works. Run agend web --code on the AgEnD computer for a new one.",
|
|
29
29
|
resend_refused_web: "A new code could not be sent. Run agend web --code on the AgEnD computer for one.",
|
|
30
|
-
// #3008: through the link "Allow connections from outside" opened — the authenticator app's code (the leader's wording).
|
|
31
|
-
label_outside: "Authenticator code", lead_outside: "Open your authenticator app and enter the 6-digit code for AgEnD.",
|
|
32
|
-
hint_outside: "Lost your phone? On the AgEnD computer, choose \u201cSet up again\u201d.",
|
|
33
|
-
refused_outside: "That code didn't work. Check that your phone's clock is right and try the newest code.",
|
|
34
|
-
paused_outside: "Too many wrong codes. Try again in {duration}.",
|
|
35
|
-
minutes: "{0} minutes", minute: "1 minute", hours: "{0} hours", hour: "1 hour",
|
|
36
30
|
},
|
|
37
31
|
"zh-TW": {
|
|
38
32
|
checking: "正在確認登入狀態…", title: "登入 AgEnD", lead: "輸入登入碼。",
|
|
@@ -50,35 +44,16 @@
|
|
|
50
44
|
hint_web: "在 AgEnD 電腦上執行 agend web --code 取得登入碼。",
|
|
51
45
|
refused_web: "登入碼無效或已失效。請在 AgEnD 電腦上執行 agend web --code 取得新碼。",
|
|
52
46
|
resend_refused_web: "無法傳送新的登入碼。請在 AgEnD 電腦上執行 agend web --code 取得。",
|
|
53
|
-
label_outside: "驗證器代碼", lead_outside: "打開驗證器 App,輸入 AgEnD 的 6 位數代碼。",
|
|
54
|
-
hint_outside: "手機遺失?請在 AgEnD 電腦上選「重新設定」。",
|
|
55
|
-
refused_outside: "代碼不對。請確認手機時間正確,並輸入最新的代碼。",
|
|
56
|
-
paused_outside: "錯誤次數太多,請 {duration} 後再試。",
|
|
57
|
-
minutes: "{0} 分鐘", minute: "1 分鐘", hours: "{0} 小時", hour: "1 小時",
|
|
58
47
|
},
|
|
59
48
|
};
|
|
60
49
|
const lang = /^zh/i.test(navigator.language || "") ? "zh-TW" : "en";
|
|
61
50
|
// #2910 D5: the server marks a web-only fleet's page (<body data-web-only="1">): its own words where it has them.
|
|
62
51
|
const webOnly = !!document.body && document.body.getAttribute("data-web-only") === "1";
|
|
63
|
-
|
|
64
|
-
// is the authenticator app's code, posted to /auth/totp.
|
|
65
|
-
const outside = webOnly && document.body.getAttribute("data-outside") === "1";
|
|
66
|
-
const t = (k) => (outside && (T[lang][`${k}_outside`] || T.en[`${k}_outside`])) || (webOnly && (T[lang][`${k}_web`] || T.en[`${k}_web`])) || T[lang][k] || T.en[k] || k;
|
|
67
|
-
/** A wait as words: "15 minutes" / 「15 分鐘」, "2 hours" / 「2 小時」 (rounded up). */
|
|
68
|
-
const duration = (ms) => {
|
|
69
|
-
const minutes = Math.max(1, Math.ceil(ms / 60000));
|
|
70
|
-
if (minutes < 60) return minutes === 1 ? t("minute") : t("minutes").replace("{0}", String(minutes));
|
|
71
|
-
const hours = Math.ceil(minutes / 60);
|
|
72
|
-
return hours === 1 ? t("hour") : t("hours").replace("{0}", String(hours));
|
|
73
|
-
};
|
|
52
|
+
const t = (k) => (webOnly && (T[lang][`${k}_web`] || T.en[`${k}_web`])) || T[lang][k] || T.en[k] || k;
|
|
74
53
|
// …and no "No chat bot?" help: the hint above already is it.
|
|
75
54
|
if (webOnly) document.querySelectorAll("details.help").forEach((d) => { if (d.querySelector && d.querySelector('[data-i18n="nobot"]')) d.hidden = true; });
|
|
76
55
|
document.documentElement.lang = lang === "zh-TW" ? "zh-Hant" : "en";
|
|
77
|
-
|
|
78
|
-
const input = $("code");
|
|
79
|
-
input.setAttribute("inputmode", "numeric"); input.setAttribute("maxlength", "7"); input.setAttribute("placeholder", "123456");
|
|
80
|
-
input.setAttribute("pattern", "[0-9 ]*");
|
|
81
|
-
}
|
|
56
|
+
$("checking").setAttribute?.("aria-label", t("checking"));
|
|
82
57
|
|
|
83
58
|
// An old dashboard link carries `?token=`. It is not a credential any more (the server ignored it and
|
|
84
59
|
// answered with this page), but it is still the fleet's token: take it out of the address bar and
|
|
@@ -151,10 +126,8 @@
|
|
|
151
126
|
offerResend();
|
|
152
127
|
}
|
|
153
128
|
|
|
154
|
-
// Only a returning device gets the button; the answer is a boolean and asking has no side effect.
|
|
155
|
-
// (#3008): the code there is the app's, nothing is sent.
|
|
129
|
+
// Only a returning device gets the button; the answer is a boolean and asking has no side effect.
|
|
156
130
|
async function offerResend() {
|
|
157
|
-
if (outside) return;
|
|
158
131
|
try {
|
|
159
132
|
const r = await fetch("/auth/device", { credentials: "same-origin", cache: "no-store" });
|
|
160
133
|
if (r.ok && (await r.json()).returning === true) $("resend").hidden = false;
|
|
@@ -201,24 +174,18 @@
|
|
|
201
174
|
button.disabled = true;
|
|
202
175
|
button.textContent = t("working");
|
|
203
176
|
try {
|
|
204
|
-
const r = await fetch(
|
|
177
|
+
const r = await fetch("/auth/login", {
|
|
205
178
|
method: "POST",
|
|
206
179
|
credentials: "same-origin",
|
|
207
180
|
headers: { "Content-Type": "application/json" },
|
|
208
181
|
body: JSON.stringify({ code: $("code").value }),
|
|
209
182
|
});
|
|
210
183
|
if (r.ok) { clearBounce(); location.replace(nextTarget()); return; }
|
|
211
|
-
if (outside && r.status === 429) {
|
|
212
|
-
let wait = Number(r.headers.get("Retry-After")) * 1000;
|
|
213
|
-
try { const body = await r.json(); if (Number.isFinite(body && body.retryAfterMs)) wait = body.retryAfterMs; } catch { /* the header's */ }
|
|
214
|
-
msg.textContent = t("paused").replace("{duration}", duration(Number.isFinite(wait) && wait > 0 ? wait : 60000));
|
|
215
|
-
throw "shown";
|
|
216
|
-
}
|
|
217
184
|
// #1854: a 5xx is the server failing to confirm the sign-in (503: a public link's notice did not go out), not a
|
|
218
185
|
// wrong code — say so. The code is spent either way: the way on is a new one.
|
|
219
186
|
msg.textContent = r.status === 429 ? t("paused") : r.status >= 500 ? t("unconfirmed") : t("refused");
|
|
220
|
-
} catch
|
|
221
|
-
|
|
187
|
+
} catch {
|
|
188
|
+
msg.textContent = t("network");
|
|
222
189
|
}
|
|
223
190
|
button.disabled = false;
|
|
224
191
|
button.textContent = t("submit");
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
|
|
47
47
|
/* ── Layout ── */
|
|
48
48
|
--col: 768px; /* the conversation column */
|
|
49
|
-
--settings-width: 1200px; /* settings workspace, including its horizontal padding */
|
|
50
49
|
--sidebar-w: 260px;
|
|
51
50
|
--header-h: 52px;
|
|
52
51
|
--tap: 44px; /* the smallest touch target on a phone */
|
|
@@ -10,7 +10,7 @@ import { t } from "./app-i18n.js";
|
|
|
10
10
|
* <${Dialog} title="Create task" onClose=${…} actions=${html`…`}>…body…</${Dialog}>
|
|
11
11
|
* Rendered = open; the parent unmounts it to close. `busy` keeps Esc and the backdrop from closing it mid-request.
|
|
12
12
|
*/
|
|
13
|
-
export function Dialog({ title, onClose, actions, children, busy = false, wide = false, drawer = false, label, tools = null
|
|
13
|
+
export function Dialog({ title, onClose, actions, children, busy = false, wide = false, drawer = false, label, tools = null }) {
|
|
14
14
|
const ref = useRef(null);
|
|
15
15
|
const opener = useRef(null);
|
|
16
16
|
const busyRef = useRef(busy);
|
|
@@ -41,7 +41,7 @@ export function Dialog({ title, onClose, actions, children, busy = false, wide =
|
|
|
41
41
|
d.addEventListener("click", onClick);
|
|
42
42
|
return () => { d.removeEventListener("cancel", onCancel); d.removeEventListener("click", onClick); };
|
|
43
43
|
}, [onClose]);
|
|
44
|
-
return html`<dialog data-trust="dialog" ref=${ref} class=${`dlg${wide ? " dlg-wide" : ""}${drawer ? " dlg-drawer" : ""}
|
|
44
|
+
return html`<dialog data-trust="dialog" ref=${ref} class=${`dlg${wide ? " dlg-wide" : ""}${drawer ? " dlg-drawer" : ""}`} aria-label=${label || title}>
|
|
45
45
|
<div class="dlg-box" tabindex="-1">
|
|
46
46
|
<div class="dlg-head"><h2 class="dlg-title">${title}</h2>${tools ? html`<span class="dlg-tools">${tools}</span>` : null}
|
|
47
47
|
<button type="button" class="icon-btn dlg-x" aria-label=${t("app.close")} title=${t("app.close")} onClick=${() => { if (!busyRef.current) onClose(); }}><${Icon} name="close" /></button></div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// #1408 §7: the ⋯ menu — a button and a list of actions. Arrow keys move, Enter/Space choose, Esc closes and puts focus
|
|
2
2
|
// back on the button. Esc inside the menu is the menu's: it never reaches the app (e.g. never stops an agent's reply).
|
|
3
|
-
import { html, useEffect,
|
|
3
|
+
import { html, useEffect, useRef, useState } from "./app-html.js";
|
|
4
4
|
import { Icon } from "./ui-icons.js";
|
|
5
5
|
import { t } from "./app-i18n.js";
|
|
6
6
|
|
|
@@ -8,54 +8,34 @@ import { t } from "./app-i18n.js";
|
|
|
8
8
|
* items: [{ key, label, icon?, onSelect, danger?, disabled? }] (falsy entries are skipped). `checked` makes a radio item;
|
|
9
9
|
* `checkbox: true` with `checked` a checkbox item (#2217 hotfix: the chat's card menu), which toggles and keeps the menu
|
|
10
10
|
* open. `active`: the button shows a pressed look (what it controls is on), without changing its role.
|
|
11
|
-
* Optional `trigger` and `triggerClass` customize the button content and styling; `label` remains its accessible name.
|
|
12
11
|
*/
|
|
13
|
-
export function Menu({ items, label, icon = "more", cls = "", active = false
|
|
12
|
+
export function Menu({ items, label, icon = "more", cls = "", active = false }) {
|
|
14
13
|
const [open, setOpen] = useState(false);
|
|
15
|
-
const [placement,setPlacement] = useState("");
|
|
16
14
|
const btn = useRef(null), list = useRef(null);
|
|
17
15
|
const shown = (items || []).filter(Boolean);
|
|
18
|
-
useLayoutEffect(() => {
|
|
19
|
-
if (!open || !fit || !btn.current?.getBoundingClientRect || !list.current) return;
|
|
20
|
-
const place = () => {
|
|
21
|
-
if (!btn.current || !list.current) return;
|
|
22
|
-
const rect = btn.current.getBoundingClientRect();
|
|
23
|
-
const boundary = btn.current.closest?.(".dlg-body")?.getBoundingClientRect();
|
|
24
|
-
const top = Math.max(0,boundary?.top || 0), bottom = Math.min(window.innerHeight,boundary?.bottom || window.innerHeight);
|
|
25
|
-
const above = rect.top-top-8, below = bottom-rect.bottom-8;
|
|
26
|
-
const up = below < Math.min(list.current.scrollHeight || 280,280) && above > below;
|
|
27
|
-
const available = up ? above : below;
|
|
28
|
-
setPlacement(`${up ? " menu-up" : ""}${available < 180 ? " menu-short" : available < 280 ? " menu-compact" : ""}`);
|
|
29
|
-
};
|
|
30
|
-
place();
|
|
31
|
-
window.addEventListener("resize",place);
|
|
32
|
-
return () => window.removeEventListener("resize",place);
|
|
33
|
-
},[open,fit]);
|
|
34
16
|
useEffect(() => {
|
|
35
|
-
if (!open
|
|
17
|
+
if (!open) return undefined;
|
|
36
18
|
const first = list.current && list.current.querySelector("[role=menuitem]:not([disabled]), [role=menuitemradio]:not([disabled]), [role=menuitemcheckbox]:not([disabled])");
|
|
37
|
-
if (first) first.focus(
|
|
19
|
+
if (first) first.focus();
|
|
38
20
|
const outside = (e) => { if (list.current && !list.current.contains(e.target) && btn.current && !btn.current.contains(e.target)) setOpen(false); };
|
|
39
21
|
document.addEventListener("pointerdown", outside, true);
|
|
40
22
|
return () => document.removeEventListener("pointerdown", outside, true);
|
|
41
|
-
}, [open
|
|
23
|
+
}, [open]);
|
|
42
24
|
function onKey(e) {
|
|
43
25
|
const all = [...list.current.querySelectorAll("[role=menuitem]:not([disabled]), [role=menuitemradio]:not([disabled]), [role=menuitemcheckbox]:not([disabled])")];
|
|
44
26
|
const i = all.indexOf(document.activeElement);
|
|
45
|
-
if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); setOpen(false); btn.current && btn.current.focus(
|
|
46
|
-
else if (e.key === "Enter" || e.key === " ") { e.preventDefault(); document.activeElement?.click(); }
|
|
27
|
+
if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); setOpen(false); btn.current && btn.current.focus(); }
|
|
47
28
|
else if (e.key === "ArrowDown") { e.preventDefault(); (all[(i + 1) % all.length] || all[0])?.focus(); }
|
|
48
29
|
else if (e.key === "ArrowUp") { e.preventDefault(); (all[(i - 1 + all.length) % all.length] || all[0])?.focus(); }
|
|
49
30
|
else if (e.key === "Home") { e.preventDefault(); all[0]?.focus(); }
|
|
50
31
|
else if (e.key === "End") { e.preventDefault(); all[all.length - 1]?.focus(); }
|
|
51
32
|
else if (e.key === "Tab") setOpen(false);
|
|
52
33
|
}
|
|
53
|
-
function choose(item) {
|
|
34
|
+
function choose(item) { setOpen(false); btn.current && btn.current.focus(); item.onSelect(); }
|
|
54
35
|
return html`<div class=${`menu ${cls}`}>
|
|
55
|
-
<button ref=${btn} type="button" class=${
|
|
56
|
-
aria-label=${label || t("app.more")} title=${label || t("app.more")} onClick=${() =>
|
|
57
|
-
|
|
58
|
-
${open && !disabled ? html`<div data-trust="menu" ref=${list} class=${`menu-list${fit ? placement : ""}`} role="menu" aria-label=${label || t("app.more")} onKeyDown=${onKey}>
|
|
36
|
+
<button ref=${btn} type="button" class=${`icon-btn${active ? " active" : ""}`} aria-haspopup="menu" aria-expanded=${open ? "true" : "false"}
|
|
37
|
+
aria-label=${label || t("app.more")} title=${label || t("app.more")} onClick=${() => setOpen(!open)}><${Icon} name=${icon} /></button>
|
|
38
|
+
${open ? html`<div data-trust="menu" ref=${list} class="menu-list" role="menu" aria-label=${label || t("app.more")} onKeyDown=${onKey}>
|
|
59
39
|
${shown.map(item => item.heading
|
|
60
40
|
? html`<div key=${item.key} class="menu-heading" role="presentation">${item.label}</div>`
|
|
61
41
|
: item.checkbox
|
|
@@ -3,9 +3,20 @@ import { html } from "./app-html.js";
|
|
|
3
3
|
import { Icon } from "./ui-icons.js";
|
|
4
4
|
import { t } from "./app-i18n.js";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// Lazy panels can arrive in a shell with an older app.css. Keep the loading shapes in their own public stylesheet.
|
|
7
|
+
function loadingStyles() {
|
|
8
|
+
if (typeof document === "undefined" || !document.head || document.querySelector('link[href="/assets/loading.css"]')) return;
|
|
9
|
+
const link = document.createElement("link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("href", "/assets/loading.css");
|
|
10
|
+
document.head.appendChild(link);
|
|
11
|
+
}
|
|
12
|
+
/** Initial data only: retain populated content on refresh. Existing callers still get simple text lines. */
|
|
13
|
+
export function Skeleton({ lines = 3, variant = "lines", label }) {
|
|
14
|
+
loadingStyles();
|
|
15
|
+
return html`<div class=${`skeleton sk-${variant}`} role="status" aria-busy="true" aria-label=${label || t("app.loading")}>
|
|
16
|
+
<div aria-hidden="true">${Array.from({ length: lines }, (_, i) => variant === "rows" || variant === "cards"
|
|
17
|
+
? html`<div key=${i} class="sk-row"><div class="sk-line sk-thumb"></div><div class="sk-copy"><div class="sk-line"></div><div class="sk-line"></div></div><div class="sk-line sk-pill"></div></div>`
|
|
18
|
+
: html`<div key=${i} class="sk-line"></div>`)}</div>
|
|
19
|
+
</div>`;
|
|
9
20
|
}
|
|
10
21
|
|
|
11
22
|
export function Empty({ icon = "info", title, hint, action }) {
|