@songsid/agend 2.3.0-beta.24 → 2.3.0-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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.js.map +1 -1
- package/dist/agent-endpoint.js +8 -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.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 +5 -0
- package/dist/auth-api.js +21 -0
- 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 +14 -6
- 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.map +1 -1
- package/dist/backend/codex-package.js.map +1 -1
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +1 -1
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.js.map +1 -1
- 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.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.map +1 -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.js.map +1 -1
- package/dist/backend-outage.js.map +1 -1
- package/dist/binary-probe.js.map +1 -1
- package/dist/bug-report.js.map +1 -1
- package/dist/bundled-skills.js.map +1 -1
- package/dist/cache-service.js +1 -1
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.js +29 -4
- 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 +10 -1
- package/dist/channel/mcp-server.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -2
- 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/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.js +15 -9
- package/dist/cli.js.map +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.js +20 -6
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +11 -3
- 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/daemon.d.ts +3 -0
- package/dist/daemon.js +73 -3
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js.map +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.js.map +1 -1
- package/dist/delivery-consumed-watch.js.map +1 -1
- 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.js.map +1 -1
- 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 +3 -2
- 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-lock.js +3 -2
- package/dist/fleet-lock.js.map +1 -1
- package/dist/fleet-manager.d.ts +77 -6
- package/dist/fleet-manager.js +488 -147
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.js +3 -2
- package/dist/fleet-process-handlers.js.map +1 -1
- 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.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.js.map +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +2 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +2 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +36 -12
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +45 -14
- package/dist/host-memory.js.map +1 -1
- package/dist/instance-config-impact.js +6 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.js +1 -1
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +2 -0
- package/dist/instructions.js +6 -2
- 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 +22 -0
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js.map +1 -1
- 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.js.map +1 -1
- package/dist/login-manager.js.map +1 -1
- package/dist/login-shell.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.js.map +1 -1
- package/dist/needs-you-live.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.js.map +1 -1
- package/dist/outbound-schemas.d.ts +68 -68
- package/dist/outbound-schemas.js +1 -1
- 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.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.js.map +1 -1
- package/dist/public-preview.js.map +1 -1
- package/dist/public-web-gateway.js +4 -2
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +35 -1
- package/dist/public-web-link.js +142 -43
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +5 -0
- package/dist/quickstart.js +25 -16
- 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.map +1 -1
- package/dist/restart-guard.js.map +1 -1
- 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.js.map +1 -1
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/task-board-text.js +16 -11
- package/dist/scheduler/task-board-text.js.map +1 -1
- package/dist/scheduler/task-board.d.ts +50 -10
- package/dist/scheduler/task-board.js +138 -44
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/sd-notify.js.map +1 -1
- package/dist/search/search-index.js.map +1 -1
- package/dist/secret-file.js.map +1 -1
- package/dist/secret-store.js.map +1 -1
- package/dist/service-installer.d.ts +7 -1
- package/dist/service-installer.js +13 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +33 -4
- package/dist/service-plan.js +177 -8
- 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.js +6 -1
- 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 +71 -1
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +4 -0
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-control.js.map +1 -1
- package/dist/settings-effect.js +6 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +1 -0
- 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-transaction.js.map +1 -1
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-host.d.ts +5 -1
- package/dist/setup-host.js +8 -1
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +5 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.d.ts +4 -0
- package/dist/spawn-gate.js +15 -5
- package/dist/spawn-gate.js.map +1 -1
- 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 +4 -4
- package/dist/task-board-summary.js +4 -4
- package/dist/task-board-summary.js.map +1 -1
- package/dist/task-board-tool.js +3 -2
- package/dist/task-board-tool.js.map +1 -1
- package/dist/task-board-waker.js +8 -4
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -0
- package/dist/tmux-manager.js +2 -1
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +1 -1
- package/dist/tmux-read.js.map +1 -1
- 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.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.map +1 -1
- package/dist/transcript-sources.js.map +1 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- 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/public-fetch.js.map +1 -1
- package/dist/tunnel/purpose-lane.js.map +1 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +26 -2
- package/dist/ui/chat-render.js +1 -15
- package/dist/ui/chat-store.js +171 -61
- package/dist/ui/chat-strings.js +7 -2
- package/dist/ui/chat-thread.js +48 -1
- package/dist/ui/fleet-canvas-layout.js +3 -0
- package/dist/ui/fleet-canvas.js +23 -20
- 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 +18 -5
- package/dist/ui/guest-refused.html +41 -0
- package/dist/ui/image-lightbox.js +9 -3
- package/dist/ui/panel-chat.js +14 -13
- package/dist/ui/panel-settings.js +30 -12
- package/dist/ui/settings-dialogs.js +15 -6
- package/dist/ui/settings-model.js +40 -3
- package/dist/ui/settings-strings.js +38 -0
- package/dist/ui/settings-web-authority.js +7 -2
- package/dist/ui/shared/agend-auth.js +2 -0
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-prefs.js +2 -0
- package/dist/ui/shared/app-shell.js +12 -0
- package/dist/ui/shared/app-store.js +1 -0
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +132 -3
- package/dist/ui/shared/guest-refused.js +35 -0
- package/dist/ui/shared/header-tools.js +2 -2
- package/dist/ui/shared/instance-nav.js +25 -8
- package/dist/ui/shared/ui-dialog.js +2 -2
- package/dist/ui/shared/usage-dialog.js +152 -6
- package/dist/ui/shared/view-strings.js +20 -0
- package/dist/ui/shared/web-authorize.js +3 -1
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.js.map +1 -1
- package/dist/update-install.js.map +1 -1
- package/dist/update-launch.js.map +1 -1
- package/dist/update-marker.js.map +1 -1
- package/dist/update-preflight.js.map +1 -1
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/providers.d.ts +8 -0
- package/dist/usage/providers.js +6 -2
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/usage/usage-api.js +2 -1
- 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.js.map +1 -1
- package/dist/view-api.js +1 -1
- package/dist/view-api.js.map +1 -1
- package/dist/wake-coordinator.js.map +1 -1
- package/dist/web-ambient.js.map +1 -1
- package/dist/web-api.d.ts +15 -2
- package/dist/web-api.js +174 -25
- package/dist/web-api.js.map +1 -1
- package/dist/web-app-icon.js.map +1 -1
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-auth.js +5 -4
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-card.js.map +1 -1
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +41 -11
- package/dist/web-chat-history.js +93 -22
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.js.map +1 -1
- 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 +7 -7
- package/dist/web-effect.js.map +1 -1
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-guest-access.js +1 -1
- package/dist/web-guest-access.js.map +1 -1
- package/dist/web-guest-rooms.js.map +1 -1
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-icons.js.map +1 -1
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-images.js.map +1 -1
- package/dist/web-libavoid.js.map +1 -1
- 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.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.js.map +1 -1
- package/dist/web-owner-css.js.map +1 -1
- package/dist/web-png.js.map +1 -1
- package/dist/web-prefs.js +2 -0
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-profile.js.map +1 -1
- package/dist/web-reactions.d.ts +2 -1
- package/dist/web-request-context.d.ts +5 -0
- package/dist/web-request-context.js.map +1 -1
- package/dist/web-returning-device.js +1 -1
- 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 +1 -0
- package/dist/web-settings-patch.js +6 -4
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.js.map +1 -1
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-terminal.js.map +1 -1
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-upload.d.ts +5 -1
- package/dist/web-upload.js +6 -4
- 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.js +1 -1
- package/dist/windows-shortcuts.js.map +1 -1
- package/dist/workflow-templates/default.md +1 -1
- package/dist/ws-server.js.map +1 -1
- package/dist/yaml-shared-nodes.js.map +1 -1
- package/launcher/agend-install.cjs +281 -6
- package/launcher/private-home.cjs +43 -0
- package/package.json +3 -2
- package/templates/windows-shortcuts.ps1 +1 -1
package/dist/ui/fleet-org.js
CHANGED
|
@@ -11,11 +11,11 @@ import { t, register } from "/assets/app-i18n.js";
|
|
|
11
11
|
import { chatPath } from "/assets/app-route.js";
|
|
12
12
|
import { Empty, Skeleton } from "/assets/ui-states.js";
|
|
13
13
|
import { Icon } from "/assets/ui-icons.js";
|
|
14
|
-
import { modelText } from "/assets/instance-nav.js";
|
|
14
|
+
import { backendLabel, modelText, namesOf } from "/assets/instance-nav.js";
|
|
15
15
|
|
|
16
16
|
register("org", {
|
|
17
17
|
en: {
|
|
18
|
-
title: "Org chart", general: "General", unteamed: "Not in a team", members: "{0} members", member: "1 member", instances: "{0} instances", instance: "1 instance",
|
|
18
|
+
starting: "Starting", queued: "Queued", title: "Org chart", general: "General", unteamed: "Not in a team", members: "{0} members", member: "1 member", instances: "{0} instances", instance: "1 instance",
|
|
19
19
|
needs: "Needs you", working: "Working", idle: "Idle", stuck: "Looks stuck", paused: "Paused", stopped: "Stopped", crashed: "Crashed",
|
|
20
20
|
missing: "Not in the fleet", thread_discord: "Discord thread", thread_telegram: "Telegram topic", openChat: "Open chat",
|
|
21
21
|
classic: "ClassicBot room", empty: "No instances yet", emptyHint: "Instances and teams show here once the fleet has them.",
|
|
@@ -23,7 +23,7 @@ register("org", {
|
|
|
23
23
|
sending: "Sending:", queuedNote: "(queued)", workingNote: "(in progress)",
|
|
24
24
|
},
|
|
25
25
|
"zh-TW": {
|
|
26
|
-
title: "組織圖", general: "General", unteamed: "未加入 team", members: "{0} 名成員", member: "1 名成員", instances: "{0} 個 instance", instance: "1 個 instance",
|
|
26
|
+
starting: "啟動中", queued: "等待啟動", title: "組織圖", general: "General", unteamed: "未加入 team", members: "{0} 名成員", member: "1 名成員", instances: "{0} 個 instance", instance: "1 個 instance",
|
|
27
27
|
needs: "等你回應", working: "工作中", idle: "閒置", stuck: "似乎卡住", paused: "已暫停", stopped: "已停止", crashed: "已當掉",
|
|
28
28
|
missing: "不在 fleet 中", thread_discord: "Discord 討論串", thread_telegram: "Telegram topic", openChat: "開啟聊天",
|
|
29
29
|
classic: "ClassicBot 頻道", empty: "還沒有 instance", emptyHint: "fleet 有 instance 和 team 後會顯示在這裡。",
|
|
@@ -35,8 +35,8 @@ const to = (k, ...v) => t(`org.${k}`, ...v);
|
|
|
35
35
|
const count = (one, many, n) => (n === 1 ? to(one) : to(many, n));
|
|
36
36
|
|
|
37
37
|
/** The states a node can show, most pressing first (a team's summary lists them in this order). */
|
|
38
|
-
export const ORG_STATES = ["needs", "crashed", "stuck", "working", "idle", "paused", "stopped", "missing"];
|
|
39
|
-
const DOT = { needs: "warn", crashed: "bad", stuck: "warn", working: "busy", idle: "ok", paused: "off", stopped: "off", missing: "off" };
|
|
38
|
+
export const ORG_STATES = ["needs", "crashed", "stuck", "starting", "queued", "working", "idle", "paused", "stopped", "missing"];
|
|
39
|
+
const DOT = { starting: "busy", queued: "off", needs: "warn", crashed: "bad", stuck: "warn", working: "busy", idle: "ok", paused: "off", stopped: "off", missing: "off" };
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* One instance's live state, from the app store: `i` its status entry (null: the fleet does not list it), `exec` the
|
|
@@ -46,6 +46,8 @@ const DOT = { needs: "warn", crashed: "bad", stuck: "warn", working: "busy", idl
|
|
|
46
46
|
export function orgState(i, exec, awaiting, needs) {
|
|
47
47
|
if (!i) return "missing";
|
|
48
48
|
if (awaiting != null || needs > 0) return "needs";
|
|
49
|
+
if (i.startup_phase === "queued") return "queued";
|
|
50
|
+
if (i.startup_phase === "starting") return "starting";
|
|
49
51
|
if (i.status === "crashed") return "crashed";
|
|
50
52
|
if (i.status === "paused") return "paused";
|
|
51
53
|
if (i.status !== "running") return "stopped";
|
|
@@ -54,6 +56,17 @@ export function orgState(i, exec, awaiting, needs) {
|
|
|
54
56
|
return "idle";
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
/**
|
|
60
|
+
* What a node's card says (fleet-canvas.js; the Office view's desk too, fleet-office.js): its names, its state and
|
|
61
|
+
* backend (`sub`), and all of it in one line (`full`, the card's title and label).
|
|
62
|
+
*/
|
|
63
|
+
export function nodeText(n) {
|
|
64
|
+
const it = n.i;
|
|
65
|
+
const names = it ? namesOf(it) : { primary: n.name, secondary: "" };
|
|
66
|
+
const sub = it ? `${to(n.state)} · ${backendLabel(it.backend)}` : to(n.state);
|
|
67
|
+
return { primary: names.primary, secondary: names.secondary, sub, full: `${names.primary}${names.secondary ? ` (${names.secondary})` : ""} — ${sub}` };
|
|
68
|
+
}
|
|
69
|
+
|
|
57
70
|
/**
|
|
58
71
|
* The chart: the structure from /ui/org, the nodes and their states from the app store. General on top; each team with
|
|
59
72
|
* its members in fleet.yaml's order (an instance in two teams shows in both: that is its place in each); then the
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="referrer" content="no-referrer">
|
|
7
|
+
<meta name="robots" content="noindex">
|
|
8
|
+
<title>AgEnD</title>
|
|
9
|
+
<!--app-icon-->
|
|
10
|
+
<link rel="icon" href="/favicon.ico" sizes="16x16 32x32 64x64">
|
|
11
|
+
<link rel="icon" href="/favicon.svg" type="image/svg+xml" sizes="any">
|
|
12
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
|
|
13
|
+
<!--/app-icon-->
|
|
14
|
+
<script src="/assets/theme.js"></script>
|
|
15
|
+
<link rel="stylesheet" href="/assets/tokens.css">
|
|
16
|
+
<style>
|
|
17
|
+
/* What a guest's browser gets for a page it cannot open (#2399 smoke: it was the gate's bare JSON). The sign-in
|
|
18
|
+
page's look: the app's tokens, light and dark (theme.js before paint). */
|
|
19
|
+
* { box-sizing: border-box; }
|
|
20
|
+
body { margin: 0; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 16px;
|
|
21
|
+
background: var(--bg); color: var(--text); font: var(--fw-regular) var(--fs-md)/var(--lh-md) var(--font-ui); -webkit-font-smoothing: antialiased; }
|
|
22
|
+
main { width: 100%; max-width: 380px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 28px 24px; }
|
|
23
|
+
.brand { margin: 0 0 18px; font-size: var(--fs-lg); font-weight: var(--fw-bold); }
|
|
24
|
+
h1 { margin: 0 0 6px; font-size: var(--fs-xl); font-weight: var(--fw-semibold); }
|
|
25
|
+
p { margin: 0 0 18px; color: var(--text-2); }
|
|
26
|
+
a.go { display: block; width: 100%; padding: 12px; text-align: center; text-decoration: none; font: var(--fw-semibold) var(--fs-md) var(--font-ui);
|
|
27
|
+
color: var(--on-accent); background: var(--accent-fill); border-radius: var(--r-full); }
|
|
28
|
+
a.go:hover { opacity: .88; }
|
|
29
|
+
a.go:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-dim); }
|
|
30
|
+
</style>
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<main id="refused" data-why="__WHY__">
|
|
34
|
+
<div class="brand">AgEnD</div>
|
|
35
|
+
<h1 id="title">This page is not open to guests</h1>
|
|
36
|
+
<p id="lead">This page is for the fleet's members. As a guest you can use the chats shared with you.</p>
|
|
37
|
+
<a id="go" class="go" href="/ui">Open your chats</a>
|
|
38
|
+
</main>
|
|
39
|
+
<script src="/assets/guest-refused.js"></script>
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
@@ -83,12 +83,18 @@ function ImageLightbox({ items, index, opener, onClose }) {
|
|
|
83
83
|
zoom.current = z;
|
|
84
84
|
return () => { z.destroy(); zoom.current = null; };
|
|
85
85
|
}, []);
|
|
86
|
-
// Another image: hidden until it has loaded and been fitted (its load resets the zoom).
|
|
86
|
+
// Another image: hidden until it has loaded and been fitted (its load resets the zoom). A layout effect — in the same
|
|
87
|
+
// commit that set the new src, before any load can arrive: a picture already in the cache (every thumbnail above it
|
|
88
|
+
// has loaded) fires its load before a passive effect would run, and such an effect then hid it for good with the
|
|
89
|
+
// level at "…" (the report on beta.24: Next "flashes once, then the next image is not visible"). A picture that is
|
|
90
|
+
// already complete here (the same file again: no load comes) is fitted at once.
|
|
87
91
|
const first = useRef(true);
|
|
88
|
-
|
|
92
|
+
useLayoutEffect(() => {
|
|
89
93
|
if (first.current) { first.current = false; return; }
|
|
90
|
-
|
|
94
|
+
const el = img.current;
|
|
95
|
+
if (el) el.classList.remove("lb-ready");
|
|
91
96
|
setLevel(null);
|
|
97
|
+
if (el && el.complete && el.naturalWidth > 0 && zoom.current) zoom.current.reset();
|
|
92
98
|
}, [at]);
|
|
93
99
|
useEffect(() => {
|
|
94
100
|
const d = ref.current;
|
package/dist/ui/panel-chat.js
CHANGED
|
@@ -122,7 +122,9 @@ export async function setPreviewOptIn(on, commit = (apply) => apply()) {
|
|
|
122
122
|
export function boot({ stream, boot: bootData, deps = {} }) {
|
|
123
123
|
if (store) return store;
|
|
124
124
|
store = createChatStore({
|
|
125
|
-
fetch: (...a) => fetch(...a), toast, announce, t, setTimeout: (fn, ms) => setTimeout(fn, ms), confirm: confirmDialog,
|
|
125
|
+
fetch: (...a) => fetch(...a), toast, announce, t, setTimeout: (fn, ms) => setTimeout(fn, ms), confirm: confirmDialog,
|
|
126
|
+
XMLHttpRequest: typeof XMLHttpRequest === "function" ? XMLHttpRequest : undefined, // an upload's progress (chat-store.js)
|
|
127
|
+
...deps,
|
|
126
128
|
});
|
|
127
129
|
emojiIndex = createEmojiIndex((url) => (deps.fetch || fetch)(url, { credentials: "same-origin" }));
|
|
128
130
|
mentionIndex = createMentionIndex((url) => (deps.fetch || fetch)(url, { credentials: "same-origin" }));
|
|
@@ -425,6 +427,9 @@ function threadEntry(name, doc) {
|
|
|
425
427
|
canTryEffect: x => getAppEffects()?.canTry(x) === true,
|
|
426
428
|
startEffectTrial: x => { const seq = navStore.get().seq; void getAppEffects()?.startTrial(x).then(ok => { if (!ok && e.sink && navStore.get().seq === seq && document.hasFocus?.() === true && document.visibilityState === "visible") toast(t("chat.effectTrialUnavailable")); }); },
|
|
427
429
|
clickReplyButton: (id, index) => store.clickReplyButton(name, id, index), // #1266
|
|
430
|
+
retryOutgoing: (clientId) => store.retryOutgoing(name, clientId), // a failed send's Retry and Delete
|
|
431
|
+
deleteOutgoing: (clientId) => store.deleteOutgoing(name, clientId),
|
|
432
|
+
putBackOutgoing: (clientId) => { recordEdit(composerField()); store.putBackOutgoing(name, clientId); }, // undoable, as typing
|
|
428
433
|
// #2272: reply to a message (the bar above the composer), and show the one a reply quotes.
|
|
429
434
|
startReply: (x) => { store.startReply(name, x); doc.getElementById("msgIn")?.focus(); },
|
|
430
435
|
findQuoted: (key) => store.findQuoted(name, key),
|
|
@@ -446,12 +451,13 @@ function follow(name, thread) {
|
|
|
446
451
|
// #1682: the same for mention names — asked for the ids the messages carry; when names arrive, drawn again.
|
|
447
452
|
const wantEmojis = (msgs) => { if (emojiIndex && emojiIndex.wants(msgs)) emojiIndex.ensure(); if (mentionIndex) mentionIndex.ensure(msgs); };
|
|
448
453
|
const offs = [];
|
|
449
|
-
if (emojiIndex) offs.push(emojiIndex.subscribe(() => thread.render(store.
|
|
450
|
-
if (mentionIndex) offs.push(mentionIndex.subscribe(() => thread.render(store.
|
|
454
|
+
if (emojiIndex) offs.push(emojiIndex.subscribe(() => thread.render(store.threadRows(name))));
|
|
455
|
+
if (mentionIndex) offs.push(mentionIndex.subscribe(() => thread.render(store.threadRows(name))));
|
|
451
456
|
wantEmojis(store.state.msgs[name]);
|
|
452
457
|
offs.push(store.subscribe((instance, kind) => {
|
|
453
458
|
if (instance !== name) return;
|
|
454
|
-
if (kind === "msgs") { thread.render(store.
|
|
459
|
+
if (kind === "msgs") { thread.render(store.threadRows(name)); wantEmojis(store.state.msgs[name]); }
|
|
460
|
+
else if (kind === "progress") thread.progress(); // an upload moved: its bar, in place
|
|
455
461
|
else if (kind === "sent") thread.jumpLatest();
|
|
456
462
|
}));
|
|
457
463
|
offs.push(P() ? P().onChange(() => thread.refreshCards()) : () => {});
|
|
@@ -461,10 +467,10 @@ function follow(name, thread) {
|
|
|
461
467
|
const next = getAppEffects();
|
|
462
468
|
if (next === trialOwner) return;
|
|
463
469
|
trialOff?.(); trialOff = null; trialOwner = next;
|
|
464
|
-
trialOff = next?.subscribeTrial(() => thread.render(store.
|
|
470
|
+
trialOff = next?.subscribeTrial(() => thread.render(store.threadRows(name))) ?? null;
|
|
465
471
|
};
|
|
466
472
|
watchTrial();
|
|
467
|
-
offs.push(onEffectsAwake(() => { watchTrial(); thread.render(store.
|
|
473
|
+
offs.push(onEffectsAwake(() => { watchTrial(); thread.render(store.threadRows(name)); }));
|
|
468
474
|
offs.push(() => { trialOff?.(); trialOff = null; trialOwner = null; });
|
|
469
475
|
offs.push(panelStore.subscribe(() => thread.refreshCards())); // a card shows whether the panel has its block
|
|
470
476
|
return () => { for (const off of offs) off(); };
|
|
@@ -493,7 +499,7 @@ function Thread({ name, th }) {
|
|
|
493
499
|
thread.attach(sc);
|
|
494
500
|
th.current = thread;
|
|
495
501
|
// Up to date, at the reader's place (the bottom unless they had scrolled up); a kept one's cards say what they can do.
|
|
496
|
-
thread.render(store.
|
|
502
|
+
thread.render(store.threadRows(name), { restore: store.state.scrollMemo[name] ?? null });
|
|
497
503
|
if (kept) thread.refreshCards();
|
|
498
504
|
const unfollow = follow(name, thread);
|
|
499
505
|
const onScroll = () => { store.state.scrollMemo[name] = thread.onScroll(); };
|
|
@@ -546,12 +552,7 @@ function Dock({ name, inst, lease, exec, awaiting, workingLabel }) {
|
|
|
546
552
|
<${WorkBar} name=${name} lease=${lease} exec=${exec} awaiting=${awaiting} workingLabel=${workingLabel} />
|
|
547
553
|
<${CommandCard} name=${name} lease=${lease} />
|
|
548
554
|
<${QuickActions} name=${name} inst=${inst} lease=${lease} />
|
|
549
|
-
${s.failedSends[name] ? html`<div class="failed-send" role="alert"><span>${t("chat.notSent")}</span><span class="txt">${s.failedSends[name]}</span>
|
|
550
|
-
<button type="button" class="btn btn-primary btn-sm" onClick=${() => { recordEdit(composerField()); store.putBack(name); }}>${t("chat.putBack")}</button>
|
|
551
|
-
<button type="button" class="btn btn-sm" onClick=${() => store.discardFailed(name)}>${t("chat.discard")}</button></div>` : null}
|
|
552
555
|
${s.waking[name] ? html`<p class="send-waking" role="status">${t("chat.waking", name)}</p>` : null}
|
|
553
|
-
${s.sendFailures[name] ? html`<div class="failed-send send-failure" role="alert"><span>${s.sendFailures[name].error}</span>
|
|
554
|
-
<button type="button" class="btn btn-sm" disabled=${!store.canRetrySend(name)} onClick=${() => store.retrySend(name)}>${t("chat.retrySend")}</button></div>` : null}
|
|
555
556
|
<${Composer} name=${name} lease=${lease} busy=${R().isBusy(exec)} />
|
|
556
557
|
<div class="composer-row">${guestPage() ? html`<span class="guest-note" title=${t("chat.guestNote")}>${t("chat.guestNote")}</span>` : html`<${ComposerAuth} />`}<span
|
|
557
558
|
class="hint" title=${t(guestPage() ? "chat.guestMore" : "chat.composerMore")}>${t("chat.composerHint")}</span></div>
|
|
@@ -721,7 +722,7 @@ function Composer({ name, lease, busy }) {
|
|
|
721
722
|
aria-activedescendant=${pick ? optId(pick) : undefined} onInput=${onInput} onKeyDown=${onKeyDown} onPaste=${onPaste}></textarea>
|
|
722
723
|
<button id="stopBtn" type="button" class="btn btn-stop" hidden=${!busy} title=${t("chat.stopReplyTitle")}
|
|
723
724
|
disabled=${!!s.cancelling[name]} onClick=${() => store.cancelReply(name)}><${Icon} name="stop" size=${14} /><span class="stop-label">${t("chat.stopReply")}</span></button>
|
|
724
|
-
<button id="sendBtn" type="button" class="btn btn-primary btn-send" hidden=${busy && !content} disabled=${!content
|
|
725
|
+
<button id="sendBtn" type="button" class="btn btn-primary btn-send" hidden=${busy && !content} disabled=${!content}
|
|
725
726
|
onMouseDown=${(e) => e.preventDefault()}
|
|
726
727
|
aria-label=${t("chat.send")} title=${t("chat.send")} onClick=${submit}><${Icon} name="send" size=${16} /><span class="send-label">${t("chat.send")}</span></button>
|
|
727
728
|
</div></div>`;
|
|
@@ -25,10 +25,10 @@ import "./settings-strings.js";
|
|
|
25
25
|
import { api, attach, confirmedWrite, newKey } from "./settings-confirm.js";
|
|
26
26
|
import { dismissOperation, operationActive, restartFleet, startOperation, takeLeftover } from "./settings-apply.js";
|
|
27
27
|
import {
|
|
28
|
-
ACCESS_MODES, AGENT_MODES, DEFAULT_SCHEMA, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
|
|
29
|
-
changedFields, channelId, channelsOf, chLabel, connectionState, effectiveSummary, fleetModel, fromYaml, fullModelRequests, groupAgents,
|
|
28
|
+
ACCESS_MODES, AGENT_MODES, DASHBOARD_FEATURES, DEFAULT_SCHEMA, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
|
|
29
|
+
changedFields, channelId, channelsOf, chLabel, connectionState, dashboardDefault, effectiveSummary, fleetModel, fromYaml, fullModelRequests, groupAgents,
|
|
30
30
|
hasOwn, impactOf, localeOptions, defaultsImpact, requestImpact, nonNegative, positive, replyGuardSupported, shortName, STATUS_ORDER, toYaml,
|
|
31
|
-
visibilityDefault, worstImpact,
|
|
31
|
+
toolSetDefault, visibilityDefault, worstImpact,
|
|
32
32
|
} from "./settings-model.js";
|
|
33
33
|
import {
|
|
34
34
|
AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, Drawer, Feedback, Impact, Label, ModelSelect, NewBotDialog, Override,
|
|
@@ -676,8 +676,9 @@ function General({ ctx }) {
|
|
|
676
676
|
const original = useMemo(() => ({ c: structuredClone(c) }), []);
|
|
677
677
|
const [f, setF] = useState(() => ({
|
|
678
678
|
backend: d.backend || "claude-code", model: d.model || "", locale: d.locale || "", auto: String(d.auto_pause_after ?? 0),
|
|
679
|
-
agent_mode: d.agent_mode || "mcp", tool_set: d.tool_set
|
|
679
|
+
agent_mode: d.agent_mode || "mcp", tool_set: TOOL_SETS.includes(d.tool_set) ? d.tool_set : "", tool_progress: d.tool_progress ?? "off",
|
|
680
680
|
visibility: visibilityDefault(d), reply: d.reply_completion_guard ?? true, log_level: d.log_level || "info",
|
|
681
|
+
dash: Object.fromEntries(DASHBOARD_FEATURES.map((k) => [k, dashboardDefault(d, k)])),
|
|
681
682
|
hangOn: hang.enabled !== false, hang: String(hang.timeout_minutes ?? HANG_TIMEOUT_DEFAULT_MINUTES),
|
|
682
683
|
concurrency: String(startup.concurrency ?? 10), stagger: String(startup.stagger_delay_ms ?? 500),
|
|
683
684
|
classicBackend: c.backend || d.backend || "claude-code",
|
|
@@ -699,14 +700,17 @@ function General({ ctx }) {
|
|
|
699
700
|
if (!ready) return;
|
|
700
701
|
const defaultsPatch = changedFields({
|
|
701
702
|
backend: f.backend, model: f.model || undefined, locale: f.locale || null, auto_pause_after: num(f.auto),
|
|
702
|
-
agent_mode: f.agent_mode, tool_set: f.tool_set, tool_progress: f.tool_progress, cross_instance_visibility: f.visibility,
|
|
703
|
+
agent_mode: f.agent_mode, tool_set: f.tool_set || null, tool_progress: f.tool_progress, cross_instance_visibility: f.visibility,
|
|
703
704
|
reply_completion_guard: f.reply, log_level: f.log_level,
|
|
705
|
+
// The dashboard features every agent may use unless its own setting says otherwise (all three, as shown).
|
|
706
|
+
dashboard: f.dash,
|
|
704
707
|
hang_detector: { enabled: f.hangOn, timeout_minutes: num(f.hang) },
|
|
705
708
|
startup: { concurrency: num(f.concurrency), stagger_delay_ms: num(f.stagger) },
|
|
706
709
|
}, {
|
|
707
710
|
backend: d.backend || "claude-code", model: d.model || undefined, locale: d.locale || null, auto_pause_after: d.auto_pause_after ?? 0,
|
|
708
|
-
agent_mode: d.agent_mode || "mcp", tool_set: d.tool_set
|
|
711
|
+
agent_mode: d.agent_mode || "mcp", tool_set: TOOL_SETS.includes(d.tool_set) ? d.tool_set : null, tool_progress: d.tool_progress ?? "off",
|
|
709
712
|
cross_instance_visibility: visibilityDefault(d), reply_completion_guard: d.reply_completion_guard ?? true, log_level: d.log_level || "info",
|
|
713
|
+
dashboard: Object.fromEntries(DASHBOARD_FEATURES.map((k) => [k, dashboardDefault(d, k)])),
|
|
710
714
|
hang_detector: { enabled: hang.enabled !== false, timeout_minutes: hang.timeout_minutes ?? HANG_TIMEOUT_DEFAULT_MINUTES },
|
|
711
715
|
startup: { concurrency: startup.concurrency ?? 10, stagger_delay_ms: startup.stagger_delay_ms ?? 500 },
|
|
712
716
|
});
|
|
@@ -751,6 +755,11 @@ function General({ ctx }) {
|
|
|
751
755
|
<div class="field"><label class="check"><input type="checkbox" checked=${f.reply} onChange=${(e) => set("reply")(e.target.checked)} /><span>${tn("replyCompletionGuard")}</span><${Impact} schema=${schema} field="defaults.reply_completion_guard" /></label>
|
|
752
756
|
<p class="note">${fleetReply}</p></div>
|
|
753
757
|
</div>
|
|
758
|
+
<fieldset class="field dash-perms"><legend>${L(tn("dashboardAccess"), "defaults.dashboard")}</legend>
|
|
759
|
+
<p class="note">${tn("dashboardDefaultsHint")}</p>
|
|
760
|
+
${DASHBOARD_FEATURES.map((k) => html`<label key=${k} class="check"><input type="checkbox" checked=${f.dash[k]}
|
|
761
|
+
onChange=${(e) => setF((x) => ({ ...x, dash: { ...x.dash, [k]: e.target.checked } }))} /><span>${tn(`dashboard_${k}`)}</span></label>`)}
|
|
762
|
+
</fieldset>
|
|
754
763
|
</section>
|
|
755
764
|
<section class="card"><h3>ClassicBot</h3>
|
|
756
765
|
<div class="grid2">
|
|
@@ -771,7 +780,8 @@ function General({ ctx }) {
|
|
|
771
780
|
</section>
|
|
772
781
|
<${Drawer} title=${tn("advancedSection")}>
|
|
773
782
|
<section class="card"><h3>${tn("runtimeResources")}</h3><div class="grid2">
|
|
774
|
-
<div class="field">${L(tn("toolSet"), "defaults.tool_set", "g-ts")}<${Select} id="g-ts" value=${f.tool_set} onChange=${set("tool_set")}
|
|
783
|
+
<div class="field">${L(tn("toolSet"), "defaults.tool_set", "g-ts")}<${Select} id="g-ts" value=${f.tool_set} onChange=${set("tool_set")}
|
|
784
|
+
options=${[{ value: "", label: tn("toolSetUnset", toolSetDefault({}, {}), toolSetDefault({}, { general_topic: true })) }, ...TOOL_SETS]} /></div>
|
|
775
785
|
<div class="field">${L(tn("logLevel"), "defaults.log_level", "g-ll")}<${Select} id="g-ll" value=${f.log_level} onChange=${set("log_level")} options=${LOG_LEVELS} /></div>
|
|
776
786
|
<div class="field">${L(tn("agentMode"), "defaults.agent_mode", "g-am")}<${Select} id="g-am" value=${f.agent_mode} onChange=${set("agent_mode")} options=${AGENT_MODES} /></div>
|
|
777
787
|
</div></section>
|
|
@@ -813,7 +823,7 @@ function WebSection({ ctx, staged }) {
|
|
|
813
823
|
echo: web.echo_to_channel ?? true,
|
|
814
824
|
log: web.log_tab === true, // #1218: off by default
|
|
815
825
|
usagePub: web.usage_report_on_public_link === true, // #2122: off by default
|
|
816
|
-
pub: { allow_public: (web.public_link && web.public_link.allow_public) ?? true, ttl_minutes: (web.public_link && web.public_link.ttl_minutes) ?? 120, protocol: (web.public_link && web.public_link.protocol) ?? "http2", hostname: (web.public_link && web.public_link.hostname) ?? "", tunnel_token_env: (web.public_link && web.public_link.tunnel_token_env) ?? "", origin_port: (web.public_link && web.public_link.origin_port) ?? 19282 },
|
|
826
|
+
pub: { allow_public: (web.public_link && web.public_link.allow_public) ?? true, ttl_minutes: (web.public_link && web.public_link.ttl_minutes) ?? 120, protocol: (web.public_link && web.public_link.protocol) ?? "http2", hostname: (web.public_link && web.public_link.hostname) ?? "", tunnel_token_env: (web.public_link && web.public_link.tunnel_token_env) ?? "", origin_port: (web.public_link && web.public_link.origin_port) ?? 19282, auto_open: (web.public_link && web.public_link.auto_open) ?? false },
|
|
817
827
|
session: { absolute_hours: local.absolute_hours ?? null, idle_hours: local.idle_hours ?? null },
|
|
818
828
|
terminal: { enabled: term.enabled ?? null, ttl_minutes: term.ttl_minutes ?? null },
|
|
819
829
|
}), []);
|
|
@@ -828,7 +838,7 @@ function WebSection({ ctx, staged }) {
|
|
|
828
838
|
return {
|
|
829
839
|
echo: pick(pending, "echo_to_channel", original.echo), log: pick(pending, "log_tab", original.log), usagePub: pick(pending, "usage_report_on_public_link", original.usagePub),
|
|
830
840
|
pub: pick(pub, "allow_public", original.pub.allow_public), ttl: String(pick(pub, "ttl_minutes", original.pub.ttl_minutes)), protocol: pick(pub, "protocol", original.pub.protocol),
|
|
831
|
-
hostname: pick(pub, "hostname", original.pub.hostname), originPort: String(pick(pub, "origin_port", original.pub.origin_port)),
|
|
841
|
+
hostname: pick(pub, "hostname", original.pub.hostname), originPort: String(pick(pub, "origin_port", original.pub.origin_port)), autoOpen: pick(pub, "auto_open", original.pub.auto_open),
|
|
832
842
|
abs: text(pick(session, "absolute_hours", original.session.absolute_hours)), idle: text(pick(session, "idle_hours", original.session.idle_hours)),
|
|
833
843
|
termOn: pick(terminal, "enabled", original.terminal.enabled) !== false, termTtl: text(pick(terminal, "ttl_minutes", original.terminal.ttl_minutes)),
|
|
834
844
|
};
|
|
@@ -841,10 +851,15 @@ function WebSection({ ctx, staged }) {
|
|
|
841
851
|
// The defaults (#1670: 48 h / 48 h, DEFAULT_SESSION_POLICY); an idle time left blank follows a shorter session, as
|
|
842
852
|
// the store and the validator apply it — so only an idle time that is typed can exceed the session length.
|
|
843
853
|
const abs = value(f.abs) ?? 48, idle = value(f.idle) ?? Math.min(48, abs);
|
|
854
|
+
// Named mode: a hostname is typed (the server judges the merged result the same way).
|
|
855
|
+
const named = String(f.hostname || "").trim() !== "";
|
|
844
856
|
const errors = {
|
|
845
857
|
hostname: f.hostname && !/^(?:https:\/\/)?[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+\/?$/.test(f.hostname) ? "namedHostnameInvalid" : "",
|
|
846
858
|
originPort: !Number.isInteger(Number(f.originPort)) || Number(f.originPort) < 1024 || Number(f.originPort) > 65535 ? "namedPortInvalid" : "",
|
|
847
|
-
ttl:
|
|
859
|
+
// #named-link-ttl: a fixed hostname (named tunnel) allows up to 7 days, or 0 = no expiry; a quick tunnel 1–480.
|
|
860
|
+
ttl: String(f.ttl).trim() === "" || !Number.isInteger(Number(f.ttl)) || Number(f.ttl) < (named ? 0 : 1) || Number(f.ttl) > (named ? 10080 : 480)
|
|
861
|
+
? (named ? "publicTtlNamedRange" : "publicTtlQuickRange") : "",
|
|
862
|
+
autoOpen: f.autoOpen && !named ? "publicAutoOpenNeedsHostname" : "",
|
|
848
863
|
abs: hours(f.abs),
|
|
849
864
|
idle: hours(f.idle) || (!hours(f.abs) && idle > abs ? "sessionIdleOver" : ""),
|
|
850
865
|
termTtl: value(f.termTtl) !== null && (!Number.isInteger(value(f.termTtl)) || value(f.termTtl) < 1 || value(f.termTtl) > 20) ? "webTerminalTtlRange" : "",
|
|
@@ -857,7 +872,7 @@ function WebSection({ ctx, staged }) {
|
|
|
857
872
|
// reference adopts the standard env key; mounting or editing an unrelated field never rewrites credentials.
|
|
858
873
|
const tokenEnv = f.hostname === original.pub.hostname ? original.pub.tunnel_token_env
|
|
859
874
|
: f.hostname ? original.pub.tunnel_token_env || "AGEND_CLOUDFLARE_TUNNEL_TOKEN" : "";
|
|
860
|
-
const publicPatch = changedFields({ allow_public: f.pub, ttl_minutes: Number(f.ttl), protocol: f.protocol, hostname: f.hostname, tunnel_token_env: tokenEnv, origin_port: Number(f.originPort) }, original.pub);
|
|
875
|
+
const publicPatch = changedFields({ allow_public: f.pub, ttl_minutes: Number(f.ttl), protocol: f.protocol, hostname: f.hostname, tunnel_token_env: tokenEnv, origin_port: Number(f.originPort), auto_open: f.autoOpen }, original.pub);
|
|
861
876
|
const sessionPatch = changedFields({ absolute_hours: value(f.abs), idle_hours: value(f.idle) }, original.session);
|
|
862
877
|
// The checkbox shows the default (on) for an unset key: only a real toggle is written; on again = back to the default.
|
|
863
878
|
const terminalPatch = changedFields({ enabled: f.termOn === (original.terminal.enabled !== false) ? original.terminal.enabled : f.termOn ? null : false,
|
|
@@ -931,9 +946,12 @@ function WebSection({ ctx, staged }) {
|
|
|
931
946
|
</div>
|
|
932
947
|
<p class="note">${tn("namedTunnelHint")} <a href="https://github.com/songsid/AgEnD/blob/main/docs/named-tunnel.md" target="_blank" rel="noopener noreferrer">${tn("namedTunnelSetup")}</a></p>
|
|
933
948
|
<div class="grid2">
|
|
934
|
-
<div class="field"><label for="publicWebTtl">${tn("publicTtl")}</label><input id="publicWebTtl" type="number" min
|
|
949
|
+
<div class="field"><label for="publicWebTtl">${tn(named ? "publicTtlNamed" : "publicTtl")}</label><input id="publicWebTtl" type="number" min=${named ? "0" : "1"} max=${named ? "10080" : "480"} step="1" class=${errors.ttl ? "invalid" : ""} value=${f.ttl} onInput=${(e) => set("ttl")(e.target.value)} /><${Feedback} error=${errors.ttl} /></div>
|
|
935
950
|
<div class="field"><label for="publicWebProtocol">${tn("publicProtocol")}</label><${Select} id="publicWebProtocol" value=${f.protocol} onChange=${set("protocol")} options=${["http2", "quic", "auto"]} /></div>
|
|
936
951
|
</div>
|
|
952
|
+
${named ? html`<p class="note" id="publicTtlNamedHint">${tn("publicTtlNamedHint")}</p>` : null}
|
|
953
|
+
${named || f.autoOpen ? html`<label class="check"><input id="publicAutoOpen" type="checkbox" checked=${f.autoOpen} onChange=${(e) => set("autoOpen")(e.target.checked)} /><span>${tn("publicAutoOpen")}</span><${Impact} schema=${schema} field="web.public_link.auto_open" /></label>
|
|
954
|
+
<p class="note">${tn("publicAutoOpenHint")}</p><${Feedback} error=${errors.autoOpen} />` : null}
|
|
937
955
|
</section>
|
|
938
956
|
</fieldset>
|
|
939
957
|
${overPublicLink ? null : html`<${PublicTunnelToken} /><${GuestsCard} ctx=${ctx} staged=${staged} /><${WebAuthorityCard} ctx=${ctx} staged=${staged} />`}
|
|
@@ -17,10 +17,10 @@ import { startOperation } from "./settings-apply.js";
|
|
|
17
17
|
import "./settings-strings.js"; // its words, wherever a picker of this file is used (#2072: Fleet's create dialog too)
|
|
18
18
|
import { backendChoices, modelChoices, OTHER_MODEL, useBackendRows, useModelCatalog } from "./settings-catalog.js";
|
|
19
19
|
import {
|
|
20
|
-
ACCESS_MODES, AGENT_MODES, CH_TYPES, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS,
|
|
20
|
+
ACCESS_MODES, AGENT_MODES, CH_TYPES, DASHBOARD_CHOICES, DASHBOARD_FEATURES, HANG_TIMEOUT_DEFAULT_MINUTES, LOG_LEVELS, TOOL_PROGRESS, TOOL_SETS,
|
|
21
21
|
VISIBILITY_MODES, accessConfirmations, agentForm, agentPatch, backendOptions, changedFields, channelId, channelsOf,
|
|
22
|
-
chLabel, hasOwn, impactOf, newConnectionImpact, nonNegative, nonNegativeInteger, positive, replyGuardSupported, sameValue, visibilityDefault,
|
|
23
|
-
classicWebEchoEffective, worstImpact,
|
|
22
|
+
chLabel, dashboardDefault, hasOwn, impactOf, newConnectionImpact, nonNegative, nonNegativeInteger, positive, replyGuardSupported, sameValue, visibilityDefault,
|
|
23
|
+
classicWebEchoEffective, toolSetDefault, worstImpact,
|
|
24
24
|
} from "./settings-model.js";
|
|
25
25
|
/** #2342: a field by id, for recordEdit before a pick or a reset writes it. */
|
|
26
26
|
const byId = (id) => (typeof document !== "undefined" ? document.getElementById(id) : null);
|
|
@@ -230,7 +230,7 @@ function EmojiPicker({ cat, keyName, platform, channel, onPick, onClose }) {
|
|
|
230
230
|
export function AgentDialog({ name, inst, ctx, onClose }) {
|
|
231
231
|
const { fleet, schema } = ctx;
|
|
232
232
|
const defaults = fleet.defaults || {};
|
|
233
|
-
const [f, setF] = useState(() => agentForm(inst, defaults));
|
|
233
|
+
const [f, setF] = useState(() => agentForm(inst, defaults, name));
|
|
234
234
|
const [emojis, setEmojis] = useState({ value: inst.status_emojis || null, baseline: inst.status_emojis || null });
|
|
235
235
|
// #1302: the baseline is what the picker shows before anyone touches it.
|
|
236
236
|
const visibilityBaseline = useMemo(() => (hasOwn(inst, "cross_instance_visibility") ? (VISIBILITY_MODES.includes(inst.cross_instance_visibility) ? inst.cross_instance_visibility : VISIBILITY_MODES[0]) : null), []);
|
|
@@ -278,15 +278,24 @@ export function AgentDialog({ name, inst, ctx, onClose }) {
|
|
|
278
278
|
<input id="ag-hang" type="number" min="0.1" step="0.5" class=${errors.hang ? "invalid" : ""} disabled=${f.inherit.hang}
|
|
279
279
|
value=${shown("hang", f.hang, String((defaults.hang_detector && defaults.hang_detector.timeout_minutes) ?? HANG_TIMEOUT_DEFAULT_MINUTES))} onInput=${(e) => set("hang")(e.target.value)} /></${Override}>
|
|
280
280
|
<${Feedback} error=${errors.hang} /></div>
|
|
281
|
-
${[["agent_mode", "agentMode", AGENT_MODES, defaults.agent_mode || "mcp"], ["tool_set", "toolSet", TOOL_SETS, defaults
|
|
281
|
+
${[["agent_mode", "agentMode", AGENT_MODES, defaults.agent_mode || "mcp"], ["tool_set", "toolSet", TOOL_SETS, toolSetDefault(defaults, inst, name)],
|
|
282
282
|
["tool_progress", "toolProgress", TOOL_PROGRESS, defaults.tool_progress ?? "off"],
|
|
283
283
|
["cross_instance_visibility", "crossInstanceVisibility", VISIBILITY_MODES, visibilityDefault(defaults)],
|
|
284
284
|
["log_level", "logLevel", LOG_LEVELS, defaults.log_level || "info"]].map(([k, label, opts, dflt]) => html`<div key=${k} class="field">
|
|
285
285
|
${L(tn(label), `instance.${k}`, `ag-${k}`)}
|
|
286
286
|
<${Override} inherit=${f.inherit[k]} onInherit=${setInherit(k)}>
|
|
287
287
|
<${Select} id=${`ag-${k}`} value=${shown(k, f[k], dflt)} disabled=${f.inherit[k]} onChange=${set(k)}
|
|
288
|
-
options=${opts.includes(f[k]) || k === "cross_instance_visibility" ? opts : [f[k], ...opts]} /></${Override}>
|
|
288
|
+
options=${opts.includes(shown(k, f[k], dflt)) || k === "cross_instance_visibility" ? opts : [shown(k, f[k], dflt), ...opts]} /></${Override}>
|
|
289
289
|
${k === "cross_instance_visibility" ? html`<p class="note">${tn("crossInstanceVisibilityHint")}</p>` : null}</div>`)}
|
|
290
|
+
<fieldset class="field dash-perms"><legend>${L(tn("dashboardAccess"), "instance.dashboard")}</legend>
|
|
291
|
+
<p class="note">${tn("dashboardAccessHint")}</p>
|
|
292
|
+
${DASHBOARD_FEATURES.map((feature) => html`<div key=${feature} class="field">
|
|
293
|
+
<label for=${`ag-dash-${feature}`}>${tn(`dashboard_${feature}`)}</label>
|
|
294
|
+
<select id=${`ag-dash-${feature}`} value=${f.dashboard[feature]} onChange=${(e) => setF((x) => ({ ...x, dashboard: { ...x.dashboard, [feature]: e.target.value } }))}>
|
|
295
|
+
${DASHBOARD_CHOICES.map((c) => html`<option key=${c} value=${c}>${c === "inherit"
|
|
296
|
+
? tn("dashboardInherit", tn(dashboardDefault(defaults, feature) ? "dashboardOn" : "dashboardOff")) : tn(c === "on" ? "dashboardOn" : "dashboardOff")}</option>`)}
|
|
297
|
+
</select></div>`)}
|
|
298
|
+
</fieldset>
|
|
290
299
|
<div class="field">${L(tn("replyCompletionGuard"), "instance.reply_completion_guard")}
|
|
291
300
|
<${Override} inherit=${f.inherit.reply_completion_guard} onInherit=${setInherit("reply_completion_guard")}>
|
|
292
301
|
<label class="check"><input type="checkbox" disabled=${f.inherit.reply_completion_guard} checked=${shown("reply_completion_guard", f.reply_completion_guard, defaults.reply_completion_guard ?? true)}
|
|
@@ -9,7 +9,22 @@ export const CH_TYPES = ["discord", "telegram"];
|
|
|
9
9
|
export const LOCALES = [["en", "English"], ["zh-TW", "繁體中文 (zh-TW)"]];
|
|
10
10
|
export const VISIBILITY_MODES = ["full", "summary", "hidden"];
|
|
11
11
|
export const LOG_LEVELS = ["trace", "debug", "info", "warn", "error"];
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The tool profiles a person may choose (src/tool-permissions.ts; the validator's list). `general` is not one: AgEnD
|
|
14
|
+
* gives it to a General that sets none.
|
|
15
|
+
*/
|
|
16
|
+
export const TOOL_SETS = ["worker", "coordinator", "standard", "minimal", "full"];
|
|
17
|
+
/**
|
|
18
|
+
* The profile an agent runs under while it sets none (resolveToolSet, on the config as loaded: the defaults merged
|
|
19
|
+
* under the agent's own): the fleet default's, else `general` for a General — its own `general_topic`, else the
|
|
20
|
+
* default's (#2407 review: `defaults.general_topic: true` makes every agent without its own a General), or the instance
|
|
21
|
+
* named general — else `worker`; never `full`, which the page used to show.
|
|
22
|
+
*/
|
|
23
|
+
export function toolSetDefault(defaults, inst, name = "") {
|
|
24
|
+
if (TOOL_SETS.includes(defaults && defaults.tool_set)) return defaults.tool_set;
|
|
25
|
+
const general = hasOwn(inst, "general_topic") ? inst.general_topic === true : !!defaults && defaults.general_topic === true;
|
|
26
|
+
return general || name === "general" ? "general" : "worker";
|
|
27
|
+
}
|
|
13
28
|
export const TOOL_PROGRESS = ["off", "standard", "verbose"];
|
|
14
29
|
export const AGENT_MODES = ["mcp", "cli"];
|
|
15
30
|
export const ACCESS_MODES = ["locked", "open", "pairing"];
|
|
@@ -23,6 +38,23 @@ export function changedFields(next, baseline) {
|
|
|
23
38
|
return Object.fromEntries(Object.entries(next).filter(([key, value]) => !sameValue(value, baseline[key])));
|
|
24
39
|
}
|
|
25
40
|
|
|
41
|
+
/**
|
|
42
|
+
* The dashboard features an agent may use (dashboard-permissions.ts): each "inherit" (the fleet default: `defaults.dashboard`,
|
|
43
|
+
* else allowed), "on" or "off". The patch names only the features that changed: null follows the default again.
|
|
44
|
+
*/
|
|
45
|
+
export const DASHBOARD_FEATURES = ["appearance", "task_board", "web_settings"];
|
|
46
|
+
export const DASHBOARD_CHOICES = ["inherit", "on", "off"];
|
|
47
|
+
const dashboardOf = (v) => (v && typeof v === "object" && !Array.isArray(v) ? v : {});
|
|
48
|
+
/** What a feature is for an agent with no setting of its own: the default's, else allowed. */
|
|
49
|
+
export const dashboardDefault = (defaults, feature) => dashboardOf(defaults && defaults.dashboard)[feature] !== false;
|
|
50
|
+
export function dashboardForm(inst) {
|
|
51
|
+
const own = dashboardOf(inst.dashboard);
|
|
52
|
+
return Object.fromEntries(DASHBOARD_FEATURES.map((f) => [f, own[f] === true ? "on" : own[f] === false ? "off" : "inherit"]));
|
|
53
|
+
}
|
|
54
|
+
export function dashboardPatchValue(choices) {
|
|
55
|
+
return Object.fromEntries(DASHBOARD_FEATURES.map((f) => [f, choices[f] === "on" ? true : choices[f] === "off" ? false : null]));
|
|
56
|
+
}
|
|
57
|
+
|
|
26
58
|
/** #1302: cross-instance notices. Unset, or a value the fleet does not know, means full. */
|
|
27
59
|
export const visibilityDefault = (defaults) => (VISIBILITY_MODES.includes(defaults && defaults.cross_instance_visibility) ? defaults.cross_instance_visibility : "full");
|
|
28
60
|
|
|
@@ -140,6 +172,7 @@ export function agentPatch(form, inst, defaults, visibilityBaseline, statusEmoji
|
|
|
140
172
|
model_failover: form.inherit.model_failover ? null : (form.model_failover.trim() ? [form.model_failover.trim()] : []),
|
|
141
173
|
display_name: form.inherit.display_name ? null : form.display_name.trim(),
|
|
142
174
|
status_emojis: form.status_emojis,
|
|
175
|
+
dashboard: dashboardPatchValue(form.dashboard),
|
|
143
176
|
};
|
|
144
177
|
return changedFields(next, {
|
|
145
178
|
backend: inst.backend || defaults.backend || "claude-code",
|
|
@@ -162,11 +195,12 @@ export function agentPatch(form, inst, defaults, visibilityBaseline, statusEmoji
|
|
|
162
195
|
model_failover: hasOwn(inst, "model_failover") ? inst.model_failover : null,
|
|
163
196
|
display_name: hasOwn(inst, "display_name") ? inst.display_name : null,
|
|
164
197
|
status_emojis: statusEmojisBaseline,
|
|
198
|
+
dashboard: dashboardPatchValue(dashboardForm(inst)),
|
|
165
199
|
});
|
|
166
200
|
}
|
|
167
201
|
|
|
168
202
|
/** The agent form's starting values (an override shows the inherited value while "inherit" is on). */
|
|
169
|
-
export function agentForm(inst, defaults) {
|
|
203
|
+
export function agentForm(inst, defaults, name = "") {
|
|
170
204
|
const hang = inst.hang_detector || {};
|
|
171
205
|
const inherit = (key) => !hasOwn(inst, key);
|
|
172
206
|
return {
|
|
@@ -177,7 +211,9 @@ export function agentForm(inst, defaults) {
|
|
|
177
211
|
auto_pause_after: String(inst.auto_pause_after ?? defaults.auto_pause_after ?? 0),
|
|
178
212
|
hang: String(hang.timeout_minutes ?? (defaults.hang_detector && defaults.hang_detector.timeout_minutes) ?? HANG_TIMEOUT_DEFAULT_MINUTES),
|
|
179
213
|
agent_mode: inst.agent_mode || defaults.agent_mode || "mcp",
|
|
180
|
-
|
|
214
|
+
// What the picker offers when the agent sets its own: a profile a person may choose (a General's inherited
|
|
215
|
+
// `general` is shown while inheriting, but not offered to write back).
|
|
216
|
+
tool_set: TOOL_SETS.includes(inst.tool_set) ? inst.tool_set : TOOL_SETS.includes(toolSetDefault(defaults, inst, name)) ? toolSetDefault(defaults, inst, name) : "worker",
|
|
181
217
|
tool_progress: inst.tool_progress ?? defaults.tool_progress ?? "off",
|
|
182
218
|
// #1302: a value the fleet does not know (a typo) is read as unset — the picker shows "full", as the old page did,
|
|
183
219
|
// and the baseline is that same "full", so an unrelated edit never writes the typo back (the server refuses it).
|
|
@@ -190,6 +226,7 @@ export function agentForm(inst, defaults) {
|
|
|
190
226
|
model_failover: Array.isArray(inst.model_failover) ? (inst.model_failover[0] || "") : ((defaults.model_failover && defaults.model_failover[0]) || ""),
|
|
191
227
|
display_name: inst.display_name ?? defaults.display_name ?? "",
|
|
192
228
|
status_emojis: inst.status_emojis || null,
|
|
229
|
+
dashboard: dashboardForm(inst),
|
|
193
230
|
inherit: {
|
|
194
231
|
auto_pause_after: inherit("auto_pause_after"), hang: !hasOwn(hang, "timeout_minutes"), agent_mode: inherit("agent_mode"),
|
|
195
232
|
tool_set: inherit("tool_set"), tool_progress: inherit("tool_progress"), cross_instance_visibility: inherit("cross_instance_visibility"),
|
|
@@ -12,6 +12,13 @@ register("settings", {
|
|
|
12
12
|
publicLink: "Offer temporary public web links",
|
|
13
13
|
publicLinkHint: "Explicit admin consent on every request. Cloudflare handles TLS; link users have full web-admin access. HTML previews get a second temporary tunnel unless web.preview_on_public_link is false.",
|
|
14
14
|
publicTtl: "Public link minutes (1–480)",
|
|
15
|
+
publicTtlNamed: "Public link minutes (0–10080; 0 = no expiry)",
|
|
16
|
+
publicTtlNamedHint: "With a fixed hostname the link may stay open up to 7 days (10080 minutes), or 0 = no expiry: it stays open until closed or AgEnD stops. Sign-in still needs a code each time. A changed lifetime applies at the next opening; Close the link to end the current one.",
|
|
17
|
+
publicTtlQuickRange: "A quick tunnel allows 1–480 minutes. Lower it, or set a fixed hostname for longer.",
|
|
18
|
+
publicTtlNamedRange: "With a fixed hostname: a whole number from 1 to 10080, or 0 for no expiry.",
|
|
19
|
+
publicAutoOpen: "Reopen the public link when AgEnD starts",
|
|
20
|
+
publicAutoOpenHint: "Fixed hostname only. After a restart the link reopens for the admin who last opened it with /web; nothing is posted. Sign-in still needs a code (from /web, or asked for on the sign-in page by a browser that signed in before). Close or /web revoke stops it until the next /web.",
|
|
21
|
+
publicAutoOpenNeedsHostname: "Needs a fixed hostname — untick it, or keep the hostname.",
|
|
15
22
|
publicProtocol: "Tunnel protocol",
|
|
16
23
|
namedHostname: "Fixed public hostname (optional)",
|
|
17
24
|
namedOriginPort: "Named tunnel origin port",
|
|
@@ -86,10 +93,20 @@ register("settings", {
|
|
|
86
93
|
hangTimeout: "Stuck timeout",
|
|
87
94
|
agentMode: "Agent mode",
|
|
88
95
|
toolSet: "Tool set",
|
|
96
|
+
toolSetUnset: "Not set ({0}; a General: {1})",
|
|
89
97
|
toolProgress: "Tool progress",
|
|
90
98
|
crossInstanceVisibility: "Bot-to-bot messages in topics",
|
|
91
99
|
crossInstanceVisibilityHint: "full: the whole message · summary: one line · hidden: nothing. Messages are always delivered; the Mirror Topic still shows them.",
|
|
92
100
|
replyCompletionGuard: "Require a delivered reply",
|
|
101
|
+
dashboardAccess: "Dashboard access",
|
|
102
|
+
dashboardAccessHint: "What this agent may use on the dashboard, on top of its tool set. Switching a feature off applies at once (its tools are refused and leave its tool list); switching one on is confirmed first.",
|
|
103
|
+
dashboard_appearance: "Its look (theme, pictures, widgets, effects, mod proposals)",
|
|
104
|
+
dashboard_task_board: "The task board",
|
|
105
|
+
dashboard_web_settings: "Your web appearance settings",
|
|
106
|
+
dashboardInherit: "Fleet default ({0})",
|
|
107
|
+
dashboardOn: "allowed",
|
|
108
|
+
dashboardOff: "off",
|
|
109
|
+
dashboardDefaultsHint: "What every agent may use on the dashboard unless its own setting (its dialog under Agents) says otherwise. Unticking applies at once; ticking is confirmed first.",
|
|
93
110
|
replyGuardSupported: "Available for Claude Code, Codex, Muse and Kiro legacy/TUI in MCP mode.",
|
|
94
111
|
replyGuardUnsupported: "Stored but inactive: {0} in {1} mode does not support reply-drop recovery.",
|
|
95
112
|
logLevel: "Log level",
|
|
@@ -505,6 +522,8 @@ register("settings", {
|
|
|
505
522
|
vaEnabled: "Web messages carry authority", vaEnabledHint: "On by default: a session carries authority only once its account confirms it from Discord or Telegram. Off: no web message carries authority, and any already given reads as none at once; authority given before it was turned off never comes back.",
|
|
506
523
|
vaStuckOff: "Web authority is off for now: its state could not be saved on this computer (see the fleet log). It comes back on by itself once it can be.",
|
|
507
524
|
vaLoopbackOnly: "Only this computer can authorize", vaLoopbackOnlyHint: "On: only a browser on this computer qualifies, not one on your network or tailnet, and authority already given from elsewhere reads as none. Turning it off again doesn't bring that back.",
|
|
525
|
+
vaNamedLink: "Also over my named link ({0})", vaNamedLinkHint: "On: a browser signed in over your own named-tunnel hostname may be authorized too (the same Confirm in your DM). It is reached from the internet, and Cloudflare sees its traffic: turning this on is confirmed in a General or on this computer. Off applies at once, and every authorization given over it reads as none. A quick tunnel never qualifies.",
|
|
526
|
+
vaSessionNamed: "over your named link",
|
|
508
527
|
vaLanWarning: "The dashboard also answers to {0} (web.allowed_hosts). Anyone who reaches it there with a stolen sign-in could give authority in your name. Turn on \"Only this computer can authorize\" unless you trust everyone who can reach it.",
|
|
509
528
|
vaHours: "An authorization lasts (hours, {0}–{1})", vaHoursRange: "Must be a number from 1 to 48",
|
|
510
529
|
vaSessionsTitle: "Authorized sessions", vaSessionsNone: "No session is authorized now.", vaSessionUntil: "Authorized {0} · until {1}",
|
|
@@ -628,6 +647,13 @@ register("settings", {
|
|
|
628
647
|
publicLink: "提供臨時公開網頁連結",
|
|
629
648
|
publicLinkHint: "每次都需管理員明確啟用。Cloudflare 終止 TLS;登入者具有完整網頁管理權限。HTML 預覽會另開一條臨時通道,除非設定 web.preview_on_public_link: false。",
|
|
630
649
|
publicTtl: "公開連結分鐘數(1–480)",
|
|
650
|
+
publicTtlNamed: "公開連結分鐘數(0–10080;0 = 不到期)",
|
|
651
|
+
publicTtlNamedHint: "設定固定網域時,連結最長可開 7 天(10080 分鐘);設 0 則不會到期,直到關閉或 AgEnD 停止。每次登入仍需登入碼。修改後的期限從下次開啟起生效;要結束目前的連結,請按「關閉」。",
|
|
652
|
+
publicTtlQuickRange: "Quick tunnel 只能設 1–480 分鐘。請調低,或設定固定網域以使用更長時間。",
|
|
653
|
+
publicTtlNamedRange: "設定固定網域時:請輸入 1 到 10080 的整數,或 0 代表不到期。",
|
|
654
|
+
publicAutoOpen: "AgEnD 啟動時重新開啟公開連結",
|
|
655
|
+
publicAutoOpenHint: "僅限固定網域。重新啟動後,會替上次用 /web 開啟連結的管理員重新開啟;不會發任何訊息。登入仍需登入碼(用 /web 取得,或由曾登入過的瀏覽器在登入頁索取)。按「關閉」或 /web revoke 後,直到下次 /web 前都不會自動開啟。",
|
|
656
|
+
publicAutoOpenNeedsHostname: "需要固定網域——請取消勾選,或保留網域。",
|
|
631
657
|
publicProtocol: "Tunnel 協定",
|
|
632
658
|
namedHostname: "固定公開網域(選用)",
|
|
633
659
|
namedOriginPort: "Named tunnel 本機連接埠",
|
|
@@ -677,10 +703,20 @@ register("settings", {
|
|
|
677
703
|
hangTimeout: "卡住逾時",
|
|
678
704
|
agentMode: "Agent 模式",
|
|
679
705
|
toolSet: "工具集",
|
|
706
|
+
toolSetUnset: "未設定({0};General 為 {1})",
|
|
680
707
|
toolProgress: "工具進度",
|
|
681
708
|
crossInstanceVisibility: "Agent 之間的訊息在主題中",
|
|
682
709
|
crossInstanceVisibilityHint: "full:完整訊息 · summary:一行摘要 · hidden:不顯示。訊息一律照常送達,Mirror Topic 也照常顯示。",
|
|
683
710
|
replyCompletionGuard: "要求送出回覆",
|
|
711
|
+
dashboardAccess: "Dashboard 權限",
|
|
712
|
+
dashboardAccessHint: "這個 agent 能在 dashboard 上用哪些功能(在工具組之外再加一層限制)。關掉立即生效(工具會被拒絕,也從它的工具清單拿掉);打開要先確認。",
|
|
713
|
+
dashboard_appearance: "它的外觀(主題、圖片、小工具、特效、mod 提案)",
|
|
714
|
+
dashboard_task_board: "任務看板",
|
|
715
|
+
dashboard_web_settings: "你的網頁外觀設定",
|
|
716
|
+
dashboardInherit: "跟 fleet 預設({0})",
|
|
717
|
+
dashboardOn: "允許",
|
|
718
|
+
dashboardOff: "關閉",
|
|
719
|
+
dashboardDefaultsHint: "每個 agent 預設能在 dashboard 上用哪些功能;個別 agent 可以在 Agents 裡它的對話框另外設定。取消勾選立即生效;勾選要先確認。",
|
|
684
720
|
replyGuardSupported: "Claude Code、Codex、Muse 與 Kiro legacy/TUI 的 MCP 模式可用。",
|
|
685
721
|
replyGuardUnsupported: "設定會保留,但不會生效:{0} 的 {1} 模式不支援回覆遺失補救。",
|
|
686
722
|
logLevel: "Log 等級",
|
|
@@ -1095,6 +1131,8 @@ register("settings", {
|
|
|
1095
1131
|
vaEnabled: "網頁訊息帶有授權", vaEnabledHint: "預設開啟:session 要等它的帳號在 Discord 或 Telegram 上確認後才帶有授權。關閉:網頁訊息都不帶授權,已給出的授權立即視為無;關閉前給出的授權不會恢復。",
|
|
1096
1132
|
vaStuckOff: "網頁授權目前是關閉的:它的狀態無法存到這台電腦上(請看 fleet 紀錄)。可以存入後會自動恢復。",
|
|
1097
1133
|
vaLoopbackOnly: "只有這台電腦可以授權", vaLoopbackOnlyHint: "開啟:只有這台電腦上的瀏覽器符合,網路或 tailnet 上的不算,之前從其他地方給出的授權視為無。再關掉也不會讓那些授權恢復。",
|
|
1134
|
+
vaNamedLink: "也允許透過我的固定網域({0})", vaNamedLinkHint: "開啟:透過你自己的 named tunnel 固定網域登入的瀏覽器也能被授權(一樣要在私訊按「確認」)。它可從網際網路連到,Cloudflare 也看得到流量:開啟需在 General 或這台電腦上確認。關閉立即生效,透過它給出的授權都視為無。Quick tunnel 一律不行。",
|
|
1135
|
+
vaSessionNamed: "透過你的固定網域",
|
|
1098
1136
|
vaLanWarning: "dashboard 也接受 {0} 的連線(web.allowed_hosts)。任何人只要從那裡連上、又拿到被盜的登入,就能以你的名義給出授權。除非你信任所有能連到那裡的人,否則請開啟「只有這台電腦可以授權」。",
|
|
1099
1137
|
vaHours: "一次授權的有效期(小時,{0}–{1})", vaHoursRange: "必須是 1 到 48 之間的數字",
|
|
1100
1138
|
vaSessionsTitle: "已授權的 session", vaSessionsNone: "目前沒有已授權的 session。", vaSessionUntil: "{0} 授權 · 到 {1}",
|