@songsid/agend 2.3.5-alpha.3 → 2.3.5-alpha.5
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/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/accounts-view.d.ts +97 -0
- package/dist/accounts-view.js +116 -0
- package/dist/accounts-view.js.map +1 -0
- 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 +3 -1
- package/dist/agent-endpoint.js +13 -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-runtime-api.d.ts +4 -0
- package/dist/agent-runtime-api.js +59 -0
- package/dist/agent-runtime-api.js.map +1 -0
- package/dist/agent-runtime-change.d.ts +76 -0
- package/dist/agent-runtime-change.js +114 -0
- package/dist/agent-runtime-change.js.map +1 -0
- package/dist/agent-workspace.d.ts +93 -0
- package/dist/agent-workspace.js +353 -0
- package/dist/agent-workspace.js.map +1 -0
- package/dist/auth-api.d.ts +27 -0
- package/dist/auth-api.js +168 -3
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/session-authorizations.d.ts +28 -4
- package/dist/authority/session-authorizations.js +63 -17
- package/dist/authority/session-authorizations.js.map +1 -1
- package/dist/backend/antigravity.js +3 -1
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/codex-footer-hints.d.ts +7 -0
- package/dist/backend/codex-footer-hints.js +41 -0
- package/dist/backend/codex-footer-hints.js.map +1 -0
- 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-quota-history.d.ts +7 -0
- package/dist/backend/codex-quota-history.js +57 -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 +7 -0
- package/dist/backend/codex.js +85 -24
- 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 -1
- package/dist/backend/grok.js +301 -54
- 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/native-pane.d.ts +3 -1
- package/dist/backend/native-pane.js +2 -2
- package/dist/backend/native-pane.js.map +1 -1
- package/dist/backend/types.d.ts +13 -1
- package/dist/backend/types.js +3 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/build-provenance-cli.d.ts +3 -0
- package/dist/build-provenance-cli.js +11 -0
- package/dist/build-provenance-cli.js.map +1 -0
- package/dist/build-provenance.d.ts +20 -0
- package/dist/build-provenance.js +67 -0
- package/dist/build-provenance.js.map +1 -0
- package/dist/build-provenance.json +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/mcp-tools.js +3 -3
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +2 -0
- package/dist/claude-auth-status.d.ts +48 -0
- package/dist/claude-auth-status.js +149 -0
- package/dist/claude-auth-status.js.map +1 -0
- package/dist/cli.js +138 -37
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +21 -1
- package/dist/config-validator.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 -1
- package/dist/daemon.js +547 -25
- 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 +23 -1
- package/dist/delivery-consumed-watch.js +30 -3
- package/dist/delivery-consumed-watch.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +1 -1
- package/dist/delivery-reconciliation.js +1 -1
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/doctor.js +20 -9
- package/dist/doctor.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 +2 -0
- package/dist/fleet-manager.d.ts +362 -7
- package/dist/fleet-manager.js +1522 -91
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-windows-runtime.d.ts +8 -2
- package/dist/fleet-windows-runtime.js +93 -6
- package/dist/fleet-windows-runtime.js.map +1 -1
- package/dist/general-knowledge/skills/concepts/SKILL.md +425 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +5 -2
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +1 -0
- package/dist/general-knowledge/skills/fleet-health/SKILL.md +2 -2
- 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/session-management/SKILL.md +1 -1
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +10 -10
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +31 -15
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/general-role.d.ts +1 -1
- package/dist/general-role.js +1 -0
- package/dist/general-role.js.map +1 -1
- package/dist/hub/admission.d.ts +28 -0
- package/dist/hub/admission.js +62 -0
- package/dist/hub/admission.js.map +1 -0
- package/dist/hub/attachments/limits.d.ts +20 -0
- package/dist/hub/attachments/limits.js +48 -0
- package/dist/hub/attachments/limits.js.map +1 -0
- package/dist/hub/attachments/store.d.ts +116 -0
- package/dist/hub/attachments/store.js +246 -0
- package/dist/hub/attachments/store.js.map +1 -0
- package/dist/hub/audit/index.d.ts +62 -0
- package/dist/hub/audit/index.js +344 -0
- package/dist/hub/audit/index.js.map +1 -0
- package/dist/hub/browser-certificate.d.ts +38 -0
- package/dist/hub/browser-certificate.js +247 -0
- package/dist/hub/browser-certificate.js.map +1 -0
- package/dist/hub/buttons-model.d.ts +9 -0
- package/dist/hub/buttons-model.js +42 -0
- package/dist/hub/buttons-model.js.map +1 -0
- package/dist/hub/buttons.d.ts +54 -0
- package/dist/hub/buttons.js +346 -0
- package/dist/hub/buttons.js.map +1 -0
- package/dist/hub/catalog.d.ts +74 -0
- package/dist/hub/catalog.js +195 -0
- package/dist/hub/catalog.js.map +1 -0
- package/dist/hub/client.d.ts +69 -0
- package/dist/hub/client.js +300 -0
- package/dist/hub/client.js.map +1 -0
- package/dist/hub/compose/member.d.ts +139 -0
- package/dist/hub/compose/member.js +450 -0
- package/dist/hub/compose/member.js.map +1 -0
- package/dist/hub/compose/server.d.ts +77 -0
- package/dist/hub/compose/server.js +349 -0
- package/dist/hub/compose/server.js.map +1 -0
- package/dist/hub/compose/views.d.ts +12 -0
- package/dist/hub/compose/views.js +4 -0
- package/dist/hub/compose/views.js.map +1 -0
- package/dist/hub/db.d.ts +56 -0
- package/dist/hub/db.js +188 -0
- package/dist/hub/db.js.map +1 -0
- package/dist/hub/directory/config.d.ts +39 -0
- package/dist/hub/directory/config.js +108 -0
- package/dist/hub/directory/config.js.map +1 -0
- package/dist/hub/directory/directory.d.ts +18 -0
- package/dist/hub/directory/directory.js +320 -0
- package/dist/hub/directory/directory.js.map +1 -0
- package/dist/hub/directory/index.d.ts +7 -0
- package/dist/hub/directory/index.js +4 -0
- package/dist/hub/directory/index.js.map +1 -0
- package/dist/hub/directory/profiles.d.ts +41 -0
- package/dist/hub/directory/profiles.js +90 -0
- package/dist/hub/directory/profiles.js.map +1 -0
- package/dist/hub/directory/types.d.ts +71 -0
- package/dist/hub/directory/types.js +14 -0
- package/dist/hub/directory/types.js.map +1 -0
- package/dist/hub/execution/cli-provider.d.ts +23 -0
- package/dist/hub/execution/cli-provider.js +341 -0
- package/dist/hub/execution/cli-provider.js.map +1 -0
- package/dist/hub/execution/index.d.ts +13 -0
- package/dist/hub/execution/index.js +8 -0
- package/dist/hub/execution/index.js.map +1 -0
- package/dist/hub/execution/model-broker.d.ts +24 -0
- package/dist/hub/execution/model-broker.js +208 -0
- package/dist/hub/execution/model-broker.js.map +1 -0
- package/dist/hub/execution/provider-setup.d.ts +11 -0
- package/dist/hub/execution/provider-setup.js +21 -0
- package/dist/hub/execution/provider-setup.js.map +1 -0
- package/dist/hub/execution/sandbox-runner.d.ts +1 -0
- package/dist/hub/execution/sandbox-runner.js +221 -0
- package/dist/hub/execution/sandbox-runner.js.map +1 -0
- package/dist/hub/execution/service.d.ts +136 -0
- package/dist/hub/execution/service.js +459 -0
- package/dist/hub/execution/service.js.map +1 -0
- package/dist/hub/execution/store.d.ts +61 -0
- package/dist/hub/execution/store.js +182 -0
- package/dist/hub/execution/store.js.map +1 -0
- package/dist/hub/execution/views.d.ts +20 -0
- package/dist/hub/execution/views.js +48 -0
- package/dist/hub/execution/views.js.map +1 -0
- package/dist/hub/http/compose.d.ts +20 -0
- package/dist/hub/http/compose.js +518 -0
- package/dist/hub/http/compose.js.map +1 -0
- package/dist/hub/http/core.d.ts +49 -0
- package/dist/hub/http/core.js +124 -0
- package/dist/hub/http/core.js.map +1 -0
- package/dist/hub/http/deps.d.ts +61 -0
- package/dist/hub/http/deps.js +2 -0
- package/dist/hub/http/deps.js.map +1 -0
- package/dist/hub/http/schema.d.ts +14 -0
- package/dist/hub/http/schema.js +80 -0
- package/dist/hub/http/schema.js.map +1 -0
- package/dist/hub/identity.d.ts +32 -0
- package/dist/hub/identity.js +80 -0
- package/dist/hub/identity.js.map +1 -0
- package/dist/hub/init/browser-certificate.d.ts +9 -0
- package/dist/hub/init/browser-certificate.js +78 -0
- package/dist/hub/init/browser-certificate.js.map +1 -0
- package/dist/hub/init/browser-tls.d.ts +18 -0
- package/dist/hub/init/browser-tls.js +62 -0
- package/dist/hub/init/browser-tls.js.map +1 -0
- package/dist/hub/init/cli.d.ts +3 -0
- package/dist/hub/init/cli.js +83 -0
- package/dist/hub/init/cli.js.map +1 -0
- package/dist/hub/init/directory-certificate.d.ts +24 -0
- package/dist/hub/init/directory-certificate.js +222 -0
- package/dist/hub/init/directory-certificate.js.map +1 -0
- package/dist/hub/init/existing-fleet.d.ts +6 -0
- package/dist/hub/init/existing-fleet.js +58 -0
- package/dist/hub/init/existing-fleet.js.map +1 -0
- package/dist/hub/init/handoff.d.ts +8 -0
- package/dist/hub/init/handoff.js +36 -0
- package/dist/hub/init/handoff.js.map +1 -0
- package/dist/hub/init/identity.d.ts +5 -0
- package/dist/hub/init/identity.js +24 -0
- package/dist/hub/init/identity.js.map +1 -0
- package/dist/hub/init/initializer.d.ts +24 -0
- package/dist/hub/init/initializer.js +385 -0
- package/dist/hub/init/initializer.js.map +1 -0
- package/dist/hub/init/inventory.d.ts +17 -0
- package/dist/hub/init/inventory.js +33 -0
- package/dist/hub/init/inventory.js.map +1 -0
- package/dist/hub/init/layout.d.ts +32 -0
- package/dist/hub/init/layout.js +53 -0
- package/dist/hub/init/layout.js.map +1 -0
- package/dist/hub/init/network.d.ts +18 -0
- package/dist/hub/init/network.js +104 -0
- package/dist/hub/init/network.js.map +1 -0
- package/dist/hub/init/plan-digest.d.ts +5 -0
- package/dist/hub/init/plan-digest.js +47 -0
- package/dist/hub/init/plan-digest.js.map +1 -0
- package/dist/hub/init/prompt.d.ts +26 -0
- package/dist/hub/init/prompt.js +110 -0
- package/dist/hub/init/prompt.js.map +1 -0
- package/dist/hub/init/secret-file.d.ts +1 -0
- package/dist/hub/init/secret-file.js +59 -0
- package/dist/hub/init/secret-file.js.map +1 -0
- package/dist/hub/init/text.d.ts +127 -0
- package/dist/hub/init/text.js +247 -0
- package/dist/hub/init/text.js.map +1 -0
- package/dist/hub/init/types.d.ts +114 -0
- package/dist/hub/init/types.js +9 -0
- package/dist/hub/init/types.js.map +1 -0
- package/dist/hub/init/wizard.d.ts +34 -0
- package/dist/hub/init/wizard.js +554 -0
- package/dist/hub/init/wizard.js.map +1 -0
- package/dist/hub/initialization.d.ts +23 -0
- package/dist/hub/initialization.js +28 -0
- package/dist/hub/initialization.js.map +1 -0
- package/dist/hub/member/agent-mode.d.ts +6 -0
- package/dist/hub/member/agent-mode.js +23 -0
- package/dist/hub/member/agent-mode.js.map +1 -0
- package/dist/hub/member/attachments.d.ts +29 -0
- package/dist/hub/member/attachments.js +107 -0
- package/dist/hub/member/attachments.js.map +1 -0
- package/dist/hub/member/exposure-api.d.ts +87 -0
- package/dist/hub/member/exposure-api.js +64 -0
- package/dist/hub/member/exposure-api.js.map +1 -0
- package/dist/hub/member/exposures.d.ts +123 -0
- package/dist/hub/member/exposures.js +282 -0
- package/dist/hub/member/exposures.js.map +1 -0
- package/dist/hub/member/pairing-api.d.ts +85 -0
- package/dist/hub/member/pairing-api.js +385 -0
- package/dist/hub/member/pairing-api.js.map +1 -0
- package/dist/hub/member/quota.d.ts +20 -0
- package/dist/hub/member/quota.js +98 -0
- package/dist/hub/member/quota.js.map +1 -0
- package/dist/hub/member-journal.d.ts +104 -0
- package/dist/hub/member-journal.js +336 -0
- package/dist/hub/member-journal.js.map +1 -0
- package/dist/hub/member-reconciliation.d.ts +14 -0
- package/dist/hub/member-reconciliation.js +97 -0
- package/dist/hub/member-reconciliation.js.map +1 -0
- package/dist/hub/mount.d.ts +39 -0
- package/dist/hub/mount.js +123 -0
- package/dist/hub/mount.js.map +1 -0
- package/dist/hub/pairing-client.d.ts +17 -0
- package/dist/hub/pairing-client.js +108 -0
- package/dist/hub/pairing-client.js.map +1 -0
- package/dist/hub/pairing.d.ts +65 -0
- package/dist/hub/pairing.js +211 -0
- package/dist/hub/pairing.js.map +1 -0
- package/dist/hub/policy.d.ts +63 -0
- package/dist/hub/policy.js +147 -0
- package/dist/hub/policy.js.map +1 -0
- package/dist/hub/preview.d.ts +32 -0
- package/dist/hub/preview.js +64 -0
- package/dist/hub/preview.js.map +1 -0
- package/dist/hub/private-files.d.ts +5 -0
- package/dist/hub/private-files.js +44 -0
- package/dist/hub/private-files.js.map +1 -0
- package/dist/hub/profile.d.ts +59 -0
- package/dist/hub/profile.js +73 -0
- package/dist/hub/profile.js.map +1 -0
- package/dist/hub/protocol.d.ts +779 -0
- package/dist/hub/protocol.js +93 -0
- package/dist/hub/protocol.js.map +1 -0
- package/dist/hub/quota.d.ts +24 -0
- package/dist/hub/quota.js +112 -0
- package/dist/hub/quota.js.map +1 -0
- package/dist/hub/representative.d.ts +141 -0
- package/dist/hub/representative.js +528 -0
- package/dist/hub/representative.js.map +1 -0
- package/dist/hub/retention.d.ts +17 -0
- package/dist/hub/retention.js +45 -0
- package/dist/hub/retention.js.map +1 -0
- package/dist/hub/rooms.d.ts +120 -0
- package/dist/hub/rooms.js +535 -0
- package/dist/hub/rooms.js.map +1 -0
- package/dist/hub/runtime.d.ts +106 -0
- package/dist/hub/runtime.js +298 -0
- package/dist/hub/runtime.js.map +1 -0
- package/dist/hub/server.d.ts +56 -0
- package/dist/hub/server.js +202 -0
- package/dist/hub/server.js.map +1 -0
- package/dist/hub/service-start.d.ts +17 -0
- package/dist/hub/service-start.js +109 -0
- package/dist/hub/service-start.js.map +1 -0
- package/dist/hub/sessions.d.ts +53 -0
- package/dist/hub/sessions.js +196 -0
- package/dist/hub/sessions.js.map +1 -0
- package/dist/hub/socket.d.ts +24 -0
- package/dist/hub/socket.js +79 -0
- package/dist/hub/socket.js.map +1 -0
- package/dist/hub/store.d.ts +77 -0
- package/dist/hub/store.js +88 -0
- package/dist/hub/store.js.map +1 -0
- package/dist/hub/tls.d.ts +31 -0
- package/dist/hub/tls.js +135 -0
- package/dist/hub/tls.js.map +1 -0
- package/dist/hub/types.d.ts +401 -0
- package/dist/hub/types.js +2 -0
- package/dist/hub/types.js.map +1 -0
- package/dist/hub/validation.d.ts +33 -0
- package/dist/hub/validation.js +136 -0
- package/dist/hub/validation.js.map +1 -0
- package/dist/hub/version-floor.d.ts +10 -0
- package/dist/hub/version-floor.js +45 -0
- package/dist/hub/version-floor.js.map +1 -0
- package/dist/hub-browser-certificate-policy.d.ts +31 -0
- package/dist/hub-browser-certificate-policy.js +25 -0
- package/dist/hub-browser-certificate-policy.js.map +1 -0
- package/dist/hub-membership-settings.d.ts +6 -0
- package/dist/hub-membership-settings.js +21 -0
- package/dist/hub-membership-settings.js.map +1 -0
- package/dist/hub-mode.d.ts +15 -0
- package/dist/hub-mode.js +17 -0
- package/dist/hub-mode.js.map +1 -0
- package/dist/hub-pairing-summary.d.ts +48 -0
- package/dist/hub-pairing-summary.js +36 -0
- package/dist/hub-pairing-summary.js.map +1 -0
- package/dist/hub-report-target.d.ts +32 -0
- package/dist/hub-report-target.js +33 -0
- package/dist/hub-report-target.js.map +1 -0
- package/dist/hub-retention-policy.d.ts +14 -0
- package/dist/hub-retention-policy.js +15 -0
- package/dist/hub-retention-policy.js.map +1 -0
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +17 -2
- package/dist/instance-lifecycle.js +58 -8
- 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 -1
- package/dist/instructions.js +1 -1
- 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/launchd-service-domain.d.ts +5 -0
- package/dist/launchd-service-domain.js +21 -0
- package/dist/launchd-service-domain.js.map +1 -0
- package/dist/locale.js +125 -3
- 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 +15 -7
- package/dist/login-flows.js +29 -3
- 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/ls-rows.js +3 -4
- package/dist/ls-rows.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/native-instance-api.d.ts +0 -1
- package/dist/native-instance-api.js +15 -3
- package/dist/native-instance-api.js.map +1 -1
- package/dist/native-instance-input.d.ts +3 -0
- package/dist/native-instance-input.js +6 -1
- package/dist/native-instance-input.js.map +1 -1
- package/dist/native-instance-registry.d.ts +6 -0
- package/dist/native-instance-registry.js +24 -0
- package/dist/native-instance-registry.js.map +1 -1
- package/dist/native-mcp.d.ts +3 -0
- package/dist/native-mcp.js +15 -2
- package/dist/native-mcp.js.map +1 -1
- package/dist/native-pane-lifecycle.d.ts +8 -0
- package/dist/native-pane-lifecycle.js +13 -4
- package/dist/native-pane-lifecycle.js.map +1 -1
- package/dist/native-pane-manager.js +17 -9
- package/dist/native-pane-manager.js.map +1 -1
- package/dist/needs-you-hub.d.ts +9 -1
- package/dist/needs-you-hub.js +46 -8
- package/dist/needs-you-hub.js.map +1 -1
- package/dist/needs-you.d.ts +47 -2
- package/dist/needs-you.js +31 -3
- package/dist/needs-you.js.map +1 -1
- package/dist/office-share-page.js +3 -3
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share.d.ts +11 -0
- package/dist/office-share.js +14 -0
- package/dist/office-share.js.map +1 -1
- package/dist/office-talk.d.ts +26 -0
- package/dist/office-talk.js +50 -0
- package/dist/office-talk.js.map +1 -0
- package/dist/outbound-handlers.d.ts +14 -0
- package/dist/outbound-handlers.js +49 -6
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +33 -1
- package/dist/outbound-schemas.js +29 -16
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-quota-history.d.ts +9 -0
- package/dist/pane-quota-history.js +67 -0
- package/dist/pane-quota-history.js.map +1 -0
- package/dist/pause-marker.d.ts +1 -1
- package/dist/pause-marker.js +1 -1
- package/dist/pause-marker.js.map +1 -1
- 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 +7 -0
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +6 -0
- package/dist/public-web-link.js +9 -0
- 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.d.ts +13 -0
- package/dist/quickstart.js +81 -5
- package/dist/quickstart.js.map +1 -1
- 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/runtime-api.d.ts +2 -0
- package/dist/runtime-api.js +106 -13
- package/dist/runtime-api.js.map +1 -1
- package/dist/runtime-build-info.d.ts +9 -0
- package/dist/runtime-build-info.js +59 -0
- package/dist/runtime-build-info.js.map +1 -0
- package/dist/runtime-bundle.d.ts +6 -1
- package/dist/runtime-bundle.js +17 -9
- package/dist/runtime-bundle.js.map +1 -1
- package/dist/runtime-cli.d.ts +13 -1
- package/dist/runtime-cli.js +173 -19
- package/dist/runtime-cli.js.map +1 -1
- package/dist/runtime-client-store.d.ts +27 -1
- package/dist/runtime-client-store.js +86 -6
- package/dist/runtime-client-store.js.map +1 -1
- package/dist/runtime-client.d.ts +74 -0
- package/dist/runtime-client.js +336 -26
- package/dist/runtime-client.js.map +1 -1
- package/dist/runtime-connection.d.ts +22 -0
- package/dist/runtime-connection.js +93 -0
- package/dist/runtime-connection.js.map +1 -0
- package/dist/runtime-coordinator.d.ts +16 -0
- package/dist/runtime-coordinator.js +287 -62
- package/dist/runtime-coordinator.js.map +1 -1
- package/dist/runtime-credential-profiles.d.ts +78 -0
- package/dist/runtime-credential-profiles.js +280 -0
- package/dist/runtime-credential-profiles.js.map +1 -0
- package/dist/runtime-install.d.ts +50 -0
- package/dist/runtime-install.js +186 -0
- package/dist/runtime-install.js.map +1 -0
- package/dist/runtime-pane-assets.d.ts +1 -1
- package/dist/runtime-pane-assets.js +1 -1
- package/dist/runtime-pane-assets.js.map +1 -1
- package/dist/runtime-pane-boot.d.ts +7 -0
- package/dist/runtime-pane-boot.js +23 -0
- package/dist/runtime-pane-boot.js.map +1 -1
- package/dist/runtime-pane-codex-index.d.ts +10 -1
- package/dist/runtime-pane-codex-index.js +131 -27
- package/dist/runtime-pane-codex-index.js.map +1 -1
- package/dist/runtime-pane-host.d.ts +19 -0
- package/dist/runtime-pane-host.js +50 -7
- package/dist/runtime-pane-host.js.map +1 -1
- package/dist/runtime-pane-link.d.ts +7 -0
- package/dist/runtime-pane-link.js +93 -2
- package/dist/runtime-pane-link.js.map +1 -1
- package/dist/runtime-pane-mcp-relay.d.ts +1 -0
- package/dist/runtime-pane-mcp-relay.js +10 -0
- package/dist/runtime-pane-mcp-relay.js.map +1 -1
- package/dist/runtime-pane-mcp.d.ts +4 -0
- package/dist/runtime-pane-mcp.js +6 -3
- package/dist/runtime-pane-mcp.js.map +1 -1
- package/dist/runtime-pane-native.d.ts +32 -2
- package/dist/runtime-pane-native.js +55 -6
- package/dist/runtime-pane-native.js.map +1 -1
- package/dist/runtime-pane-port.d.ts +5 -0
- package/dist/runtime-pane-port.js +17 -1
- package/dist/runtime-pane-port.js.map +1 -1
- package/dist/runtime-pane-process.d.ts +1 -1
- package/dist/runtime-pane-process.js +11 -2
- package/dist/runtime-pane-process.js.map +1 -1
- package/dist/runtime-pane-protocol.d.ts +11 -1
- package/dist/runtime-pane-protocol.js +27 -5
- package/dist/runtime-pane-protocol.js.map +1 -1
- package/dist/runtime-pane-quota-history.d.ts +6 -0
- package/dist/runtime-pane-quota-history.js +44 -0
- package/dist/runtime-pane-quota-history.js.map +1 -0
- package/dist/runtime-pane-service.d.ts +5 -0
- package/dist/runtime-pane-service.js +47 -12
- package/dist/runtime-pane-service.js.map +1 -1
- package/dist/runtime-pane-transcript.d.ts +5 -0
- package/dist/runtime-pane-transcript.js +66 -5
- package/dist/runtime-pane-transcript.js.map +1 -1
- package/dist/runtime-pane-worker.js +19 -6
- package/dist/runtime-pane-worker.js.map +1 -1
- package/dist/runtime-protocol.d.ts +30 -2
- package/dist/runtime-protocol.js +30 -0
- package/dist/runtime-protocol.js.map +1 -1
- package/dist/runtime-update-activity.d.ts +21 -0
- package/dist/runtime-update-activity.js +51 -0
- package/dist/runtime-update-activity.js.map +1 -0
- package/dist/runtime-update-artifact.d.ts +31 -0
- package/dist/runtime-update-artifact.js +252 -0
- package/dist/runtime-update-artifact.js.map +1 -0
- package/dist/runtime-update-install.d.ts +31 -0
- package/dist/runtime-update-install.js +205 -0
- package/dist/runtime-update-install.js.map +1 -0
- package/dist/runtime-update-journal.d.ts +44 -0
- package/dist/runtime-update-journal.js +121 -0
- package/dist/runtime-update-journal.js.map +1 -0
- package/dist/runtime-update-lock.d.ts +48 -0
- package/dist/runtime-update-lock.js +217 -0
- package/dist/runtime-update-lock.js.map +1 -0
- package/dist/runtime-update-owners.d.ts +29 -0
- package/dist/runtime-update-owners.js +240 -0
- package/dist/runtime-update-owners.js.map +1 -0
- package/dist/runtime-update-protocol.d.ts +15 -0
- package/dist/runtime-update-protocol.js +13 -0
- package/dist/runtime-update-protocol.js.map +1 -0
- package/dist/runtime-windows-bridge.d.ts +2 -1
- package/dist/runtime-windows-bridge.js +11 -1
- package/dist/runtime-windows-bridge.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-text.js +1 -1
- package/dist/scheduler/task-board-text.js.map +1 -1
- package/dist/scheduler/task-board.d.ts +13 -0
- package/dist/scheduler/task-board.js +28 -3
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/service-drain.d.ts +19 -0
- package/dist/service-drain.js +64 -0
- package/dist/service-drain.js.map +1 -0
- package/dist/service-installer.d.ts +7 -2
- package/dist/service-installer.js +13 -10
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +20 -0
- package/dist/settings-api.js +414 -4
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +6 -0
- package/dist/settings-baseline.js +3 -1
- package/dist/settings-baseline.js.map +1 -1
- package/dist/settings-change.js +29 -6
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.d.ts +13 -0
- package/dist/settings-effect.js +98 -1
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +3 -0
- package/dist/settings-http-confirmation.js +28 -1
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-instance-patch.js +27 -0
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-wizard.js +6 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/task-board-tool.d.ts +13 -1
- package/dist/task-board-tool.js +104 -4
- 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-binary.d.ts +59 -0
- package/dist/tmux-binary.js +200 -0
- package/dist/tmux-binary.js.map +1 -0
- package/dist/tmux-control.js +4 -4
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-exec-helper.js +32 -1
- package/dist/tmux-exec-helper.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -1
- package/dist/tmux-manager.js +45 -36
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.js +4 -3
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.d.ts +5 -2
- package/dist/tool-permissions.js +6 -5
- 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 +10 -5
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-monitor.d.ts +20 -0
- package/dist/transcript-monitor.js +47 -3
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-needles.d.ts +7 -0
- package/dist/transcript-needles.js +9 -1
- package/dist/transcript-needles.js.map +1 -1
- package/dist/transcript-records.d.ts +1 -1
- package/dist/transcript-records.js +2 -1
- package/dist/transcript-records.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/ui/account-identity.js +27 -0
- package/dist/ui/accounts-view.js +214 -0
- package/dist/ui/agent-runtime-settings.js +68 -0
- package/dist/ui/agent-runtime.js +20 -2
- package/dist/ui/backend-signin.js +39 -21
- package/dist/ui/chat-ambient.js +1 -1
- package/dist/ui/chat-md-strings.js +3 -0
- package/dist/ui/chat-render.js +3 -670
- package/dist/ui/chat-store.js +1 -1
- package/dist/ui/chat-strings.js +3 -333
- package/dist/ui/chat-thread.js +3 -919
- package/dist/ui/chat-time.js +3 -80
- package/dist/ui/chat-tour.js +1 -1
- package/dist/ui/credential-profile-select.js +54 -0
- package/dist/ui/fleet-office-dialogue.d.ts +30 -0
- package/dist/ui/fleet-office-dialogue.js +382 -0
- package/dist/ui/fleet-office-pack.d.ts +9 -0
- package/dist/ui/fleet-office-pack.js +76 -4
- package/dist/ui/fleet-office-skin.js +23 -5
- package/dist/ui/fleet-office-store.js +5 -0
- package/dist/ui/fleet-office.js +173 -6
- package/dist/ui/fleet-task-card.js +10 -6
- package/dist/ui/fleet-task-common.js +12 -2
- package/dist/ui/fleet-task-menu.js +188 -0
- package/dist/ui/fleet-task-stats.js +124 -0
- package/dist/ui/fleet-task-view.js +340 -0
- package/dist/ui/fleet-tasks.js +131 -43
- package/dist/ui/fleet-usage.js +90 -27
- package/dist/ui/html-attachment.js +3 -40
- package/dist/ui/hub-agent-copy.js +23 -0
- package/dist/ui/hub-button-actions.js +65 -0
- package/dist/ui/hub-chat-store.js +158 -0
- package/dist/ui/hub-chat-strings.js +77 -0
- package/dist/ui/hub-client.js +329 -0
- package/dist/ui/hub-owner-strings.js +51 -0
- package/dist/ui/hub-provider-guidance.js +31 -0
- package/dist/ui/hub-quota.js +85 -0
- package/dist/ui/hub-strings.js +162 -0
- package/dist/ui/hub-switcher.js +27 -0
- package/dist/ui/native-instance-settings.js +5 -8
- package/dist/ui/native-pane-recovery.js +1 -1
- package/dist/ui/office-share-page.js +4 -2
- package/dist/ui/panel-chat.js +36 -49
- package/dist/ui/panel-details.js +1 -1
- package/dist/ui/panel-fleet.js +82 -12
- package/dist/ui/panel-hub.js +619 -0
- package/dist/ui/panel-log.js +2 -2
- package/dist/ui/panel-needs.js +24 -8
- package/dist/ui/panel-runtimes.js +239 -45
- package/dist/ui/panel-settings.js +266 -192
- package/dist/ui/panel-windows-cli.js +88 -42
- package/dist/ui/preview-pages.js +1 -1
- package/dist/ui/preview-panel.js +92 -6
- package/dist/ui/preview-versions.js +1 -1
- package/dist/ui/preview.js +3 -476
- package/dist/ui/runtime-commands.d.ts +4 -0
- package/dist/ui/runtime-commands.js +59 -0
- package/dist/ui/search-dialog.js +2 -0
- package/dist/ui/settings-access-strings.js +42 -0
- package/dist/ui/settings-agent-filters.js +94 -0
- package/dist/ui/settings-appearance.js +122 -23
- package/dist/ui/settings-build-version.js +35 -0
- package/dist/ui/settings-codex-copy.js +19 -0
- package/dist/ui/settings-devices.js +253 -0
- package/dist/ui/settings-dialogs.js +33 -12
- package/dist/ui/settings-guests.js +25 -11
- package/dist/ui/settings-hub-browser-certificate.js +74 -0
- package/dist/ui/settings-hub-membership.js +72 -0
- package/dist/ui/settings-hub-retention.js +52 -0
- package/dist/ui/settings-hub.js +196 -0
- package/dist/ui/settings-layout.js +242 -0
- package/dist/ui/settings-model.js +24 -2
- package/dist/ui/settings-outside.js +104 -38
- package/dist/ui/settings-registry.js +9 -4
- package/dist/ui/settings-shared-strings.js +143 -0
- package/dist/ui/settings-shared.js +345 -0
- package/dist/ui/settings-shortcuts.js +65 -0
- package/dist/ui/settings-strings.js +89 -32
- package/dist/ui/settings-web-authority.js +17 -11
- package/dist/ui/shared/accounts.css +15 -0
- 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 +6 -1
- package/dist/ui/shared/app-session.js +6 -2
- package/dist/ui/shared/app-shell.js +81 -15
- package/dist/ui/shared/app.css +1114 -13
- package/dist/ui/shared/app.js +12 -3
- package/dist/ui/shared/chat-composer.js +68 -0
- package/dist/ui/shared/chat-md-strings.js +9 -0
- package/dist/ui/shared/chat-render.js +682 -0
- package/dist/ui/shared/chat-strings.js +333 -0
- package/dist/ui/shared/chat-thread.js +969 -0
- package/dist/ui/shared/chat-time.js +80 -0
- package/dist/ui/shared/header-tools.js +3 -5
- package/dist/ui/shared/html-attachment.js +42 -0
- package/dist/ui/shared/hub-chat.css +85 -0
- package/dist/ui/shared/hub-owner.css +33 -0
- package/dist/ui/shared/hub-quota.css +8 -0
- package/dist/ui/shared/hub.css +71 -0
- package/dist/ui/shared/instance-nav.js +3 -2
- package/dist/ui/shared/machine-name.js +13 -0
- package/dist/ui/shared/page-head.js +8 -0
- package/dist/ui/shared/panel-view.js +77 -4
- package/dist/ui/shared/preview.js +476 -0
- package/dist/ui/shared/runtime-install.css +26 -0
- package/dist/ui/shared/settings-width.js +31 -0
- package/dist/ui/shared/side-rail.js +15 -0
- package/dist/ui/shared/signin.js +172 -0
- package/dist/ui/shared/task-board.css +95 -0
- package/dist/ui/shared/tokens.css +1 -0
- package/dist/ui/shared/ui-dialog.js +2 -2
- package/dist/ui/shared/ui-menu.js +3 -3
- package/dist/ui/shared/usage-dialog.js +18 -1
- 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 -0
- package/dist/ui/shared/workspace.css +20 -0
- package/dist/ui/signin.html +21 -0
- package/dist/ui/windows-cli-catalog.js +41 -12
- package/dist/ui/workspace-panel.js +189 -0
- package/dist/ui/workspace-strings.js +35 -0
- package/dist/unattended-install.d.ts +11 -2
- package/dist/unattended-install.js +41 -6
- 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.js +2 -1
- 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/usage-api.d.ts +31 -0
- package/dist/usage/usage-api.js +80 -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 +105 -23
- 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 +49 -2
- package/dist/web-api.js +279 -8
- package/dist/web-api.js.map +1 -1
- package/dist/web-backend-login.d.ts +23 -1
- package/dist/web-backend-login.js +11 -17
- package/dist/web-backend-login.js.map +1 -1
- package/dist/web-device-login.d.ts +153 -0
- package/dist/web-device-login.js +278 -0
- package/dist/web-device-login.js.map +1 -0
- package/dist/web-office-skins.d.ts +9 -0
- package/dist/web-office-skins.js +16 -1
- package/dist/web-office-skins.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 +35 -0
- package/dist/web-session.js +7 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -1
- package/dist/web-settings-patch.js +4 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-shell-routes.d.ts +6 -0
- package/dist/web-shell-routes.js +7 -0
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-terminal.d.ts +4 -30
- package/dist/web-terminal.js +9 -6
- package/dist/web-terminal.js.map +1 -1
- package/dist/windows-agents.d.ts +4 -1
- package/dist/windows-agents.js +14 -10
- package/dist/windows-agents.js.map +1 -1
- package/dist/windows-cli-api.d.ts +12 -1
- package/dist/windows-cli-api.js +29 -2
- package/dist/windows-cli-api.js.map +1 -1
- package/dist/windows-cli-providers.d.ts +0 -9
- package/dist/windows-cli-providers.js +4 -9
- package/dist/windows-cli-providers.js.map +1 -1
- package/dist/windows-cli-worker.d.ts +25 -0
- package/dist/windows-cli-worker.js +98 -7
- package/dist/windows-cli-worker.js.map +1 -1
- package/dist/windows-cli.d.ts +11 -0
- package/dist/windows-cli.js +17 -3
- package/dist/windows-cli.js.map +1 -1
- package/dist/yaml-shared-nodes.js +8 -3
- package/dist/yaml-shared-nodes.js.map +1 -1
- package/launcher/agend-install.cjs +8 -1
- package/launcher/launchd-session-type.cjs +14 -0
- package/launcher/postinstall.cjs +27 -2
- package/launcher/private-home.cjs +1 -1
- package/launcher/tmux-bundle.cjs +247 -0
- package/package.json +3 -2
- package/templates/launchd.plist.ejs +3 -1
- package/templates/runtime-install/install.ps1 +270 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SettingsBuildVersion } from "./settings-build-version.js";
|
|
1
2
|
// #1408 step 3: the Settings panel (/settings[/<section>]) — agents, connections, ClassicBot rooms, general defaults,
|
|
2
3
|
// the developer YAML. Behind the session gate (/ui/js/), loaded the first time it is opened.
|
|
3
4
|
//
|
|
@@ -25,18 +26,21 @@ import { Menu } from "/assets/ui-menu.js";
|
|
|
25
26
|
import { toast } from "/assets/ui-toast.js";
|
|
26
27
|
import { GroupMark, groupLabel, groupOf as navGroupOf, modelText } from "/assets/instance-nav.js";
|
|
27
28
|
import "./settings-strings.js";
|
|
29
|
+
import "./settings-shared-strings.js"; // see settings-shared.js: the words Shared agent settings added, which an older settings-strings.js in an open tab lacks
|
|
30
|
+
import "./settings-access-strings.js"; // the words Access & security added (settings.webLoginQr…): an older settings-strings.js from a tab that visited Fleet first lacks them (#3061)
|
|
28
31
|
import { api, attach, confirmedWrite, newKey } from "./settings-confirm.js";
|
|
29
32
|
import { dismissOperation, operationActive, restartFleet, startOperation, takeLeftover } from "./settings-apply.js";
|
|
30
33
|
import {
|
|
31
|
-
ACCESS_MODES,
|
|
34
|
+
ACCESS_MODES, DASHBOARD_FEATURES, SEPARATE_FEATURE_KEYS, DEFAULT_SCHEMA, ownChoiceImpact, HANG_TIMEOUT_DEFAULT_MINUTES, TOOL_PROGRESS, TOOL_SETS, VISIBILITY_MODES, batchImpact,
|
|
32
35
|
changedFields, channelId, channelsOf, chLabel, connectionState, dashboardDefault, effectiveSummary, fleetModel, fromYaml, fullModelRequests, groupAgents,
|
|
33
|
-
hasOwn, impactOf,
|
|
34
|
-
|
|
36
|
+
hasOwn, impactOf, defaultsImpact, requestImpact, nonNegative, positive, replyGuardSupported, sameValue, shortName, STATUS_ORDER, toYaml,
|
|
37
|
+
visibilityDefault, worstImpact,
|
|
35
38
|
} from "./settings-model.js";
|
|
36
39
|
import {
|
|
37
|
-
AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, DefaultMark,
|
|
40
|
+
AgentDialog, BackendSelect, BotDialog, ChipList, ClassicDialog, DefaultMark, Feedback, Impact, InEffect, Inherited, Label,
|
|
38
41
|
NewBotDialog, Override, Select, ask, impactText, inAgentDefaults, valueText,
|
|
39
42
|
} from "./settings-dialogs.js";
|
|
43
|
+
import { SharedAgentSettings, sharedNotes } from "./settings-shared.js";
|
|
40
44
|
import { SetupWizard } from "./settings-wizard.js";
|
|
41
45
|
import { CreateInstanceDialog } from "./panel-fleet.js";
|
|
42
46
|
import { RuntimesPanel } from "./panel-runtimes.js";
|
|
@@ -46,7 +50,7 @@ import { takeAgentRequest } from "./settings-request.js";
|
|
|
46
50
|
// #1604: This device — the preview opt-in (one path: the app's confirm, then preview.js) and the tour, from the chat.
|
|
47
51
|
import { setPreviewOptIn } from "./panel-chat.js";
|
|
48
52
|
import { startTour } from "./chat-tour.js";
|
|
49
|
-
import "
|
|
53
|
+
import "/assets/chat-strings.js";
|
|
50
54
|
import { AppearanceSection } from "./settings-appearance.js";
|
|
51
55
|
import { GuestsCard } from "./settings-guests.js";
|
|
52
56
|
import { OfficeSharesCard } from "./office-share-dialog.js";
|
|
@@ -54,8 +58,32 @@ import { PageSharesCard } from "./page-share-dialog.js";
|
|
|
54
58
|
import { syncStage, useDraft } from "./settings-draft.js";
|
|
55
59
|
import { WebAuthorityCard } from "./settings-web-authority.js";
|
|
56
60
|
import { OutsideCard } from "./settings-outside.js";
|
|
61
|
+
import { DevicesCard } from "./settings-devices.js";
|
|
62
|
+
/** The pure owner Settings switch is available while off; its pairing UI remains lazy and member-mark gated. */
|
|
63
|
+
function HubCardSlot() {
|
|
64
|
+
const [Card, setCard] = useState(null);
|
|
65
|
+
useEffect(() => { let live = true; import("./settings-hub-membership.js").then((m) => { if (live) setCard(() => m.HubMembershipSettings); }, () => {}); return () => { live = false; }; }, []);
|
|
66
|
+
return Card ? html`<${Card} />` : null;
|
|
67
|
+
}
|
|
68
|
+
function HubBrowserCertificateSlot() {
|
|
69
|
+
const [Card, setCard] = useState(null);
|
|
70
|
+
useEffect(() => { let live = true; import("./settings-hub-browser-certificate.js").then(m => { if (live) setCard(() => m.HubBrowserCertificateSettings); }, () => {}); return () => { live = false; }; }, []);
|
|
71
|
+
return Card ? html`<${Card} />` : null;
|
|
72
|
+
}
|
|
73
|
+
function HubRetentionSlot() {
|
|
74
|
+
const [Card, setCard] = useState(null);
|
|
75
|
+
useEffect(() => { let live = true; import("./settings-hub-retention.js").then(m => { if (live) setCard(() => m.HubRetentionSettings); }, () => {}); return () => { live = false; }; }, []);
|
|
76
|
+
return Card ? html`<${Card} />` : null;
|
|
77
|
+
}
|
|
57
78
|
import { NamedLinkTest, setTypedTunnelToken } from "./settings-named-test.js";
|
|
58
79
|
import { SignInList } from "./backend-signin.js";
|
|
80
|
+
import { AccountsView, defaultsBackendOptions } from "./accounts-view.js"; // #3212: SignInList stays exported for a page that still imports it
|
|
81
|
+
import { ProviderMark } from "./provider-marks.js";
|
|
82
|
+
import { CliProductMark, cliLabel } from "./cli-picker.js";
|
|
83
|
+
import { SettingsPageHead, SettingsTabs, SettingsTabPanel, useSettingsTabs, revealSettingsTarget, layoutText } from "./settings-layout.js";
|
|
84
|
+
import { AgentFilters, agentFilterText, agentRuntime, agentRuntimeOffline, agentStatus, filterAgentGroups } from "./settings-agent-filters.js";
|
|
85
|
+
import { useRuntimeCatalog } from "./runtime-catalog.js";
|
|
86
|
+
import { ShortcutsHelpRow } from "./settings-shortcuts.js";
|
|
59
87
|
import { GeneralLocation } from "./general-location.js";
|
|
60
88
|
|
|
61
89
|
const tn = (k, ...v) => t(`settings.${k}`, ...v);
|
|
@@ -65,7 +93,6 @@ const APPLY_ERRORS = new Set(["unsupported_sensitive_effect", "confirmation_diff
|
|
|
65
93
|
// #2726: a code or words of the setup host (the wizard's commit) in the page's language; anything else as it came.
|
|
66
94
|
export const applyErrorText = (code) => (APPLY_ERRORS.has(code) ? tn(`applyError_${code}`) : tn("applyErrorOther", hostText(String(code), lang())));
|
|
67
95
|
const ICONS = { preferences: "user", look: "palette", agents: "bot", runtimes: "view", "agent-defaults": "sliders", chat: "chat", "web-dashboard": "globe", access: "key", advanced: "code" };
|
|
68
|
-
const RELEASES = "https://github.com/songsid/AgEnD/releases";
|
|
69
96
|
|
|
70
97
|
/** GET under the panel's lease → { ok, status, body }. */
|
|
71
98
|
async function read(lease, path) {
|
|
@@ -107,7 +134,7 @@ async function loadLive(lease) {
|
|
|
107
134
|
if (!lease.current()) return null;
|
|
108
135
|
const live = {}, classicLive = {};
|
|
109
136
|
if (f.ok && f.body && Array.isArray(f.body.instances)) for (const i of f.body.instances) {
|
|
110
|
-
live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: modelText(i, i.model_display), effort: i.effort, effort_supported: i.effort_supported, runtime:i.runtime, capabilities:i.capabilities };
|
|
137
|
+
live[i.name] = { status: i.status, state: i.state, backend: i.backend, model: i.model, model_display: modelText(i, i.model_display), effort: i.effort, effort_supported: i.effort_supported, runtime:i.runtime, capabilities:i.capabilities, machine_id:i.machine_id, machine_name:i.machine_name, machine_status:i.machine_status };
|
|
111
138
|
if (i.classic) classicLive[i.name] = { status: i.status, state: i.state };
|
|
112
139
|
}
|
|
113
140
|
// /api/fleet carries live state for ClassicBot rooms; the profiles are the fallback for one not listed there yet.
|
|
@@ -115,7 +142,7 @@ async function loadLive(lease) {
|
|
|
115
142
|
if (!lease.current()) return null;
|
|
116
143
|
const classicStatus = {};
|
|
117
144
|
if (pr.ok && Array.isArray(pr.body)) for (const r of pr.body) classicStatus[r.instance_name] = r.status;
|
|
118
|
-
return { live, classicLive, classicStatus, fleetUp: f.ok, version: (f.ok && f.body && f.body.version) || "" };
|
|
145
|
+
return { live, classicLive, classicStatus, fleetUp: f.ok, version: (f.ok && f.body && f.body.version) || "", build: f.ok && f.body ? f.body.build : null };
|
|
119
146
|
}
|
|
120
147
|
|
|
121
148
|
export function SettingsPanel({ route, navKey }) {
|
|
@@ -381,20 +408,30 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
381
408
|
const formKey = data && !data.error ? `${data.loadedAt}:${draftEpoch}` : "";
|
|
382
409
|
// #2347 regrouping: each card where the person looks for it (the IA in #2347 §3); a form split across sections (the
|
|
383
410
|
// defaults, Web) is one form with one draft, shown a part at a time.
|
|
384
|
-
const sectionBody = section === "preferences" ? html`<${DeviceSection} key=${you.key}
|
|
411
|
+
const sectionBody = section === "preferences" ? html`<${DeviceSection} key=${you.key} />`
|
|
385
412
|
: section === "look" ? html`<${AppearanceSection} ...${you} part="look" />`
|
|
386
413
|
: section === "runtimes" ? html`<${RuntimesPanel} navKey=${navKey} />`
|
|
387
414
|
: !data ? html`<${Skeleton} lines=${6} />`
|
|
388
415
|
: data.error ? html`<${ErrorState} message=${tn("configLoadFailed")} onRetry=${reload} />`
|
|
389
|
-
: section === "agents" ? html`<${YamlLock} staged=${staged}><${Agents} ctx=${ctx} search=${search} openDialog=${toDialog} /></${YamlLock}
|
|
416
|
+
: section === "agents" ? html`<${YamlLock} staged=${staged}><${Agents} ctx=${ctx} search=${search} clearSearch=${() => setSearch("")} openDialog=${toDialog} /></${YamlLock}><details class="s-ui-disclosure s-ai-accounts"><summary><span>${layoutText("aiAccounts")}</span><small>${layoutText("aiAccountsSummary")}</small></summary><div class="s-disclosure-body s-auth-body">
|
|
417
|
+
<div class="s-auth-scope"><${Icon} name="view" size=${18} /><div><strong>${layoutText("aiHostScope")}</strong><p>${layoutText("aiAccountsHint")}</p><a href=${settingsPath("runtimes")}>${layoutText("aiWindowsLink")}<span aria-hidden="true">→</span></a></div></div>
|
|
418
|
+
<${AccountsView} instances=${ctx.fleet.instances || {}} stageAgent=${ctx.stageAgent}
|
|
419
|
+
stageDefault=${(backend, profile) => {
|
|
420
|
+
// One change for every CLI's fleet default, carrying the whole map (the write replaces it whole).
|
|
421
|
+
const opts = defaultsBackendOptions((ctx.fleet.defaults || {}).backend_options, stagedRef.current.get("defaults:account")?.request?.body?.backend_options, backend, profile);
|
|
422
|
+
if (!opts) { ctx.unstage("defaults:account"); return; }
|
|
423
|
+
ctx.stage("defaults:account", { label: tn("updateDefaults"), count: 1, impact: defaultsImpact(ctx.schema, "backend_options"),
|
|
424
|
+
request: { method: "PUT", url: "/api/settings/fleet/defaults", body: { backend_options: opts } } });
|
|
425
|
+
}} />${ctx.providerOk ? html`<${ProviderKeys} ctx=${ctx} />` : html`<section class="s-auth-section s-api-unavailable"><header class="s-auth-section-head"><div><h3>${layoutText("apiKeysTitle")}</h3><p>${layoutText("apiKeysHint")}</p></div><span class="s-auth-state">${layoutText("apiKeysUnavailableState")}</span></header><p class="note">${layoutText("apiKeysUnavailable")}</p></section>`}
|
|
426
|
+
</div></details>`
|
|
390
427
|
: section === "agent-defaults" ? html`<${GeneralLocation} /><${YamlLock} staged=${staged}><${General} key=${formKey} ctx=${ctx} part="fleet" /></${YamlLock}>`
|
|
391
428
|
: section === "chat" ? html`<${YamlLock} staged=${staged}><${Bots} ctx=${ctx} search=${search} openDialog=${toDialog} /></${YamlLock}>
|
|
392
429
|
<${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="chat" />
|
|
393
|
-
<div id="classicbot" class="s-anchor"><h2 class="s-ap-group">ClassicBot</h2><${Classic} ctx=${ctx} search=${search} openDialog=${toDialog}
|
|
394
|
-
|
|
430
|
+
<div id="classicbot" class="s-anchor s-classic-area"><section class="card s-chat-classic"><h2 class="s-ap-group">ClassicBot</h2><${Classic} ctx=${ctx} search=${search} openDialog=${toDialog} /></section>
|
|
431
|
+
<details class="s-ui-disclosure s-classic-defaults"><summary>${layoutText("classicDefaults")}</summary><div class="s-disclosure-body"><${General} key=${formKey} ctx=${ctx} part="classic" /></div></details></div>`
|
|
395
432
|
: section === "web-dashboard" ? html`<${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="dashboard" /><${AppearanceSection} ...${you} part="dashboard" />`
|
|
396
433
|
: section === "access" ? html`<${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="access" />`
|
|
397
|
-
: html`<${
|
|
434
|
+
: html`<${AdvancedSettings} ctx=${ctx} staged=${staged} formKey=${formKey} draftEpoch=${draftEpoch} />`;
|
|
398
435
|
// #2347 §6: the setting a search result opened — brought into view once its section is drawn (its data may still be
|
|
399
436
|
// on its way), focused, and flashed for 2 s.
|
|
400
437
|
const wanted = useRef(null);
|
|
@@ -413,6 +450,7 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
413
450
|
if (++tries < 40) timer = setTimeout(find, 50); else wanted.current = null;
|
|
414
451
|
return;
|
|
415
452
|
}
|
|
453
|
+
if (revealSettingsTarget(el)) { timer = setTimeout(find, 0); return; }
|
|
416
454
|
wanted.current = null;
|
|
417
455
|
// #2347 §10: a setting in a closed drawer (Advanced) is shown — every drawer around it opens first.
|
|
418
456
|
for (let d = el.closest && el.closest("details"); d; d = d.parentElement && d.parentElement.closest("details")) d.open = true;
|
|
@@ -453,7 +491,14 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
453
491
|
if (!id) return;
|
|
454
492
|
let el = null;
|
|
455
493
|
try { el = document.getElementById(decodeURIComponent(id)); } catch { el = null; }
|
|
456
|
-
if (el
|
|
494
|
+
if (!el) return;
|
|
495
|
+
const show = () => {
|
|
496
|
+
// Hash links, like settings-search targets, must reveal every enclosing disclosure before scrolling.
|
|
497
|
+
for (let d = el.closest && el.closest("details"); d; d = d.parentElement && d.parentElement.closest("details")) d.open = true;
|
|
498
|
+
if (typeof el.scrollIntoView === "function") el.scrollIntoView({ block: "start" });
|
|
499
|
+
};
|
|
500
|
+
if (revealSettingsTarget(el)) { const timer = setTimeout(show, 0); return () => clearTimeout(timer); }
|
|
501
|
+
show();
|
|
457
502
|
}, [section, navKey, !!data]);
|
|
458
503
|
// A dialog belongs to the navigation that opened it (its draft names one object, never another).
|
|
459
504
|
const open = dialog && dialog.key === navKey ? dialog : null;
|
|
@@ -464,7 +509,7 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
464
509
|
// Which one is shown is the root's data-view: its class stays exactly the effects producer's ("panel p-settings", #1629).
|
|
465
510
|
const atList = typeof location !== "undefined" && location.pathname === "/settings";
|
|
466
511
|
return html`<div data-effect-panel="settings" class="panel p-settings" data-view=${atList ? "index" : "section"}>
|
|
467
|
-
<${PanelHeader} title=${tn("title")} sub=${data
|
|
512
|
+
<${PanelHeader} title=${tn("title")} sub=${data ? html`<${SettingsBuildVersion} version=${data.version} build=${data.build} />` : null}>
|
|
468
513
|
<button type="button" class="btn btn-ghost btn-sm" disabled=${!ctx || yamlStaged(staged)} title=${ctx && yamlStaged(staged) ? tn("yamlUnsaved") : undefined} onClick=${openWizard}><${Icon} name="wand" size=${16} /><span class="hide-narrow">${tn("wizardButton")}</span></button>
|
|
469
514
|
<button type="button" class="icon-btn" aria-label=${tn("helpButton")} title=${tn("helpButton")} onClick=${() => setDialog({ kind: "help", key: navKey })}><${Icon} name="info" /></button>
|
|
470
515
|
</${PanelHeader}>
|
|
@@ -472,14 +517,15 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
472
517
|
<span class="s-nav-head" id=${`s-grp-${g.id}`}>${tn(`grp_${g.id}`)}</span>
|
|
473
518
|
${g.sections.map((k) => html`<a key=${k} href=${sectionPath(k)} class=${`seg-item${k === section ? " active" : ""}`}
|
|
474
519
|
aria-current=${k === section ? "page" : undefined}><${Icon} name=${ICONS[k]} size=${16} /><span>${tn(`sec_${k}`)}</span></a>`)}</div>`)}</div></nav>
|
|
475
|
-
<div data-trust="panel-content" class="panel-body"><div class="col">
|
|
520
|
+
<div data-trust="panel-content" class="panel-body"><div class="col" data-settings-section=${section}>
|
|
476
521
|
<a class="s-back" href=${settingsPath()}><${Icon} name="back" size=${16} /><span>${tn("title")}</span><span class="s-back-here">${tn(`sec_${section}`)}</span></a>
|
|
522
|
+
${section !== "runtimes" ? html`<${SettingsPageHead} section=${section}>${section === "agents" && ctx ? html`<button type="button" id="newAgentBtn" class="btn btn-primary" disabled=${yamlStaged(staged)} onClick=${() => toDialog({ kind: "create" })}><${Icon} name="plus" size=${16} />${tn("newAgent")}</button>` : null}</${SettingsPageHead}>` : null}
|
|
477
523
|
${searchable ? html`<div class="s-toolbar"><label class="s-search"><${Icon} name="search" size=${14} /><span class="sr-only">${tn("searchAll")}</span>
|
|
478
524
|
<input type="search" value=${search} placeholder=${tn("searchAll")} onInput=${(e) => setSearch(e.target.value)} /></label></div>` : null}
|
|
479
525
|
${op ? html`<${OperationCard} op=${op} schema=${data && data.schema} />` : null}
|
|
480
526
|
<${PendingChanges} inline=${true} />
|
|
481
527
|
${ctx && (section === "agents" || section === "chat") ? html`<${FirstRunCard} onConnect=${openWizard} />` : null}
|
|
482
|
-
|
|
528
|
+
<div class="s-section-layout" data-section=${section}>${sectionBody}</div>
|
|
483
529
|
</div></div>
|
|
484
530
|
${staged.size ? html`<${PendingBar} staged=${staged} busy=${opBusy(op)} onApply=${apply} onDiscard=${discard} section=${section} />` : null}
|
|
485
531
|
${open && ctx ? renderDialog(open, ctx, close) : null}
|
|
@@ -487,6 +533,14 @@ export function SettingsPanel({ route, navKey }) {
|
|
|
487
533
|
</div>`;
|
|
488
534
|
}
|
|
489
535
|
|
|
536
|
+
function AdvancedSettings({ ctx, staged, formKey, draftEpoch }) {
|
|
537
|
+
const [tab, setTab] = useSettingsTabs("advanced", "editor");
|
|
538
|
+
return html`<div class="s-advanced-layout"><${SettingsTabs} id="advanced" value=${tab} onChange=${setTab} items=${[{ id: "editor", label: layoutText("editor") }, { id: "effective", label: layoutText("effective") }]} />
|
|
539
|
+
<${SettingsTabPanel} group="advanced" id="editor" active=${tab === "editor"}><${Developer} key=${`dev:${draftEpoch}`} ctx=${ctx} /></${SettingsTabPanel}>
|
|
540
|
+
<${SettingsTabPanel} group="advanced" id="effective" active=${tab === "effective"}><${WebSection} key=${formKey} ctx=${ctx} staged=${staged} part="readonly" /></${SettingsTabPanel}>
|
|
541
|
+
</div>`;
|
|
542
|
+
}
|
|
543
|
+
|
|
490
544
|
/**
|
|
491
545
|
* #1604, #1665: Preferences. Synced across the person's devices (kept on the host, app-prefs.js): theme (theme.js),
|
|
492
546
|
* language (app-i18n.js) and HTML previews (preview.js, through the app's confirm). On the public link they are
|
|
@@ -608,17 +662,23 @@ export function DeviceSection() {
|
|
|
608
662
|
setTimeout(go, 0);
|
|
609
663
|
};
|
|
610
664
|
const publicLink = typeof document !== "undefined" && document.body && document.body.dataset.publicLink === "1";
|
|
611
|
-
return html
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
665
|
+
return html`<div class="s-pref-stack">
|
|
666
|
+
<section class="card s-device s-pref-personal"><h3>${tn("prefsProfileGroup")}</h3>
|
|
667
|
+
<${ProfileCard} embedded=${true} />
|
|
668
|
+
<div class="s-pref-name-format"><${DevicePrefs} labels=${true} fields=${["names"]} /></div>
|
|
669
|
+
</section>
|
|
670
|
+
<section class="card s-device s-synced s-pref-content"><div class="s-pref-group-head"><h3>${tn("prefsContentGroup")}</h3><span class="s-scope" title=${publicLink ? tn("syncedPublicLink") : tn("syncedLead")}>${tn("prefsAccountScope")}</span></div>
|
|
671
|
+
${publicLink ? html`<p class="sub">${tn("syncedPublicLink")}</p>` : null}
|
|
672
|
+
<${DevicePrefs} labels=${true} fields=${["language"]} />
|
|
673
|
+
${P() ? html`<label class="check s-pref-preview"><span>${t("chat.previews")}</span><input id="pref-previews" class="s-ui-toggle" type="checkbox" checked=${on} onChange=${(e) => { const want = e.target.checked; setPreviewOptIn(want).then(setOn); }} /><small>${layoutText("previewsPersonalHint")}</small></label>` : null}
|
|
674
|
+
</section>
|
|
675
|
+
<section class="card s-device s-local s-pref-help"><h3>${tn("prefsHelpGroup")}</h3>
|
|
676
|
+
<div class="s-pref-help-row"><div><strong>${t("chat.tour")}</strong><p class="sub">${tn("prefsTourHint")}</p></div>
|
|
677
|
+
<button type="button" id="tourBtn" class="btn" title=${t("chat.tourBtnTitle")} onClick=${replay}><${Icon} name="info" size=${16} />${tn("prefsReplayTour")}</button></div>
|
|
678
|
+
<${ShortcutsHelpRow} />
|
|
679
|
+
</section>
|
|
680
|
+
<a class="s-pref-look-link" href=${settingsPath("look")}>${tn("prefsLookHint")}<${Icon} name="chevron" size=${16} /></a>
|
|
681
|
+
</div>`;
|
|
622
682
|
}
|
|
623
683
|
|
|
624
684
|
/**
|
|
@@ -628,7 +688,7 @@ export function DeviceSection() {
|
|
|
628
688
|
* refuses one; this only shows what it says.
|
|
629
689
|
*/
|
|
630
690
|
const view = (b) => ({ phase: "ready", name: b.name || "", shown: b.shown || "", id: b.id || "", bound: b.bound === true, platform: b.platform_name || "", error: "" });
|
|
631
|
-
export function ProfileCard() {
|
|
691
|
+
export function ProfileCard({ embedded = false } = {}) {
|
|
632
692
|
const [state, setState] = useState({ phase: "loading", name: "", shown: "", id: "", bound: false, platform: "", error: "" });
|
|
633
693
|
const [draft, setDraft] = useState("");
|
|
634
694
|
const lease = useLease();
|
|
@@ -655,16 +715,22 @@ export function ProfileCard() {
|
|
|
655
715
|
};
|
|
656
716
|
const busy = state.phase !== "ready";
|
|
657
717
|
const changed = draft.trim() !== state.name;
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
718
|
+
const initial = [...(state.shown || state.name || "web-user")][0]?.toUpperCase() || "W";
|
|
719
|
+
const fields = html`<div class="s-pref-profile-layout">
|
|
720
|
+
${embedded ? html`<span class="s-pref-avatar" aria-hidden="true">${initial}</span>` : null}
|
|
721
|
+
<div class="s-pref-profile-main"><div class="field"><label for="profile-name">${tn("profileName")}</label>
|
|
722
|
+
<div class="s-pref-name-action"><input id="profile-name" type="text" maxlength="200" autocomplete="nickname" value=${draft} disabled=${busy}
|
|
662
723
|
placeholder=${state.platform || "web-user"} aria-invalid=${state.error ? "true" : "false"} aria-describedby="profile-help"
|
|
663
724
|
onInput=${(e) => setDraft(e.target.value)} onKeyDown=${(e) => { if (e.key === "Enter" && changed && draft.trim()) save(false); }} />
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
725
|
+
<button type="button" class="btn primary" disabled=${busy || !changed || !draft.trim()} onClick=${() => save(false)}>${embedded ? tn("prefsSaveName") : tn("profileSave")}</button></div>
|
|
726
|
+
<p class="sub" id="profile-help">${state.error ? html`<span class="err" role="alert">${state.error}</span>` : tn("profileHelp", state.shown || "web-user", state.id)}</p>
|
|
727
|
+
</div>
|
|
728
|
+
<p class="sub s-pref-immediate">${tn("prefsNameImmediate")}</p>
|
|
729
|
+
${state.name ? html`<div class="s-device-row"><button type="button" class="btn btn-ghost btn-sm" disabled=${busy} onClick=${() => save(true)}>${state.bound ? tn("profileUseAccount", state.platform || "web-user") : tn("profileClear")}</button></div>` : null}
|
|
730
|
+
<details class="s-pref-identity-details"><summary>${layoutText("profileIdentityDetails")}</summary><p class="sub">${state.bound ? tn("profileLeadBound") : tn("profileLeadUnbound")}</p></details>
|
|
731
|
+
</div></div>`;
|
|
732
|
+
return embedded ? html`<div class="s-profile s-pref-profile-fields">${fields}</div>`
|
|
733
|
+
: html`<section class="card s-device s-profile"><h3>${tn("profileTitle")}</h3>${fields}</section>`;
|
|
668
734
|
}
|
|
669
735
|
|
|
670
736
|
/** The operation in hand still owns Apply: its writes and job, or a restart of AgEnD from the press to its end. */
|
|
@@ -761,60 +827,67 @@ function agentChannelLabel(inst, chs) {
|
|
|
761
827
|
return idx >= 0 ? `${chs[idx].type} (${chLabel(idx)})` : inst.channel_id;
|
|
762
828
|
}
|
|
763
829
|
|
|
764
|
-
function Agents({ ctx, search, openDialog }) {
|
|
830
|
+
function Agents({ ctx, search, clearSearch, openDialog }) {
|
|
765
831
|
const insts = ctx.fleet.instances || {};
|
|
766
832
|
const [collapsed, setCollapsed] = useState(() => new Set());
|
|
767
833
|
const [busy, setBusy] = useState(() => new Map()); // name → the action under way
|
|
834
|
+
const [runtime, setRuntime] = useState("");
|
|
835
|
+
const [status, setStatus] = useState("");
|
|
836
|
+
// The computers' names come from the same list as the Runtime page (revoked ones included, so an Agent still bound to one can say so).
|
|
837
|
+
const catalog = useRuntimeCatalog(Object.values(insts).some((inst) => inst?.machine_id));
|
|
838
|
+
// A fleet with remote Runtimes off answers { enabled: false, machines: [] }: that is no list, not an empty one.
|
|
839
|
+
const machines = catalog.data && catalog.data.enabled !== false ? new Map(catalog.data.machines.map((machine) => [machine.id, { name: machine.name, status: machine.status }])) : null;
|
|
768
840
|
const chs = channelsOf(ctx.fleet);
|
|
769
841
|
// #2172: the sidebar's grouping — an agent in a team under its team, else under its first tag.
|
|
770
842
|
const teamsOf = (name) => Object.keys(ctx.fleet.teams || {}).filter((t) => Array.isArray(ctx.fleet.teams[t]?.members) && ctx.fleet.teams[t].members.includes(name));
|
|
771
|
-
const groups = groupAgents(insts, ctx.live, search, (name) => navGroupOf({ tags: insts[name]?.tags, teams: teamsOf(name) }), groupLabel);
|
|
843
|
+
const groups = filterAgentGroups(groupAgents(insts, ctx.live, search, (name) => navGroupOf({ tags: insts[name]?.tags, teams: teamsOf(name) }), groupLabel), insts, ctx.live, { runtime, status });
|
|
844
|
+
const active = !!(runtime || status || search.trim());
|
|
772
845
|
// One action per agent at a time: the whole row is off (Settings and ⋯ too), and the pressed button says it is working.
|
|
773
846
|
const run = async (name, action, work) => {
|
|
774
847
|
if (busy.has(name)) return;
|
|
775
848
|
setBusy((b) => new Map(b).set(name, action));
|
|
776
849
|
try { await work(); } finally { setBusy((b) => { const n = new Map(b); n.delete(name); return n; }); }
|
|
777
850
|
};
|
|
778
|
-
const head = html
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
if (!
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
const folded = collapsed.has(group) && !
|
|
851
|
+
const head = html`<${AgentFilters} instances=${insts} live=${ctx.live} machines=${machines} runtime=${runtime} status=${status} active=${active}
|
|
852
|
+
matched=${groups.reduce((count, group) => count + group.names.length, 0)} total=${Object.keys(insts).length} onRuntime=${setRuntime} onStatus=${setStatus}
|
|
853
|
+
onClear=${() => { setRuntime(""); setStatus(""); clearSearch(); }} />`;
|
|
854
|
+
if (!Object.keys(insts).length) return html`${head}<${Empty} icon="bot" title=${tn("noAgents")} />`;
|
|
855
|
+
if (!groups.length) return html`${head}<${Empty} icon="search" title=${search.trim() ? tn("noAgentMatch", search.trim()) : agentFilterText("noMatch")} hint=${agentFilterText("noMatchHint")} />`;
|
|
856
|
+
return html`${head}<div class="s-list s-agents-list">
|
|
857
|
+
<div class="s-list-columns s-agent-columns" aria-hidden="true"><span>${tn("uiAgentColumnName")}</span><span>${agentFilterText("runtime")}</span><span>${tn("uiAgentColumnCli")}</span><span>${tn("uiListColumnState")}</span><span>${tn("uiListColumnActions")}</span></div>${groups.map(({ group, names }) => {
|
|
858
|
+
const folded = collapsed.has(group) && !active; // searching/filtering opens every matching group
|
|
786
859
|
return html`<section key=${group} class="s-group">
|
|
787
860
|
<button type="button" class="s-group-head" aria-expanded=${folded ? "false" : "true"}
|
|
788
861
|
onClick=${() => setCollapsed((c) => { const n = new Set(c); n.has(group) ? n.delete(group) : n.add(group); return n; })}>
|
|
789
862
|
<${Icon} name="chevron" size=${14} cls=${folded ? "caret folded" : "caret"} /><${GroupMark} group=${group} /><span class="grow">${groupLabel(group)}</span><span class="count">${names.length}</span></button>
|
|
790
863
|
${folded ? null : names.map((name) => {
|
|
791
864
|
const inst = insts[name];
|
|
792
|
-
const st = (ctx.live[name]
|
|
865
|
+
const st = agentStatus(ctx.live[name]);
|
|
793
866
|
const sum = effectiveSummary(ctx.live[name] || {}, inst, ctx.fleet.defaults || {});
|
|
794
867
|
const ch = agentChannelLabel(inst, chs);
|
|
795
868
|
const working = busy.has(name), doing = busy.get(name);
|
|
796
869
|
const label = (action, text) => (doing === action ? tn("working") : text);
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
<span class="s-name" title=${name}>${shortName(name, inst)}</span>
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
<span class="
|
|
870
|
+
const runtimeTarget = agentRuntime(inst, ctx.live[name], machines);
|
|
871
|
+
return html`<div key=${name} class="s-row s-agent-row">
|
|
872
|
+
<div class="s-agent-identity"><span class="s-name" title=${name}>${shortName(name, inst)}</span>
|
|
873
|
+
<div class="s-agent-context">${inst.runtime !== "windows" || ctx.live[name]?.capabilities?.effort === true ? html`<span class="tag">${tn("effortTag", sum.effort)}</span>` : null}
|
|
874
|
+
${ch ? html`<span class=${`tag${ch.includes("persona") ? " persona" : ""}`}>${ch}</span>` : null}</div>
|
|
875
|
+
</div>
|
|
876
|
+
<div class="s-agent-runtime"><span class=${`tag${runtimeTarget.gone ? " warn" : ""}`} title=${runtimeTarget.title || runtimeTarget.label}>${runtimeTarget.label}</span></div>
|
|
877
|
+
<div class="s-agent-cli"><${CliProductMark} id=${sum.backend} size=${20} /><span><strong>${cliLabel(sum.backend)}</strong><span class="s-meta" title=${sum.model}>${sum.model}</span></span></div>
|
|
878
|
+
<span class="s-agent-status"><span class=${dotClass(agentStatus(ctx.live[name]))} aria-hidden="true"></span><span>${agentFilterText(agentStatus(ctx.live[name]))}${agentRuntimeOffline(inst, ctx.live[name]) ? html`<small class="s-agent-runtime-state">${agentFilterText("offline")}</small>` : null}</span></span>
|
|
806
879
|
<span class="s-actions">
|
|
807
880
|
${inst.runtime === "windows" ? html`<a class="btn btn-sm" href=${chatPath(name)}>${t("app.chat")}</a>` : null}
|
|
808
881
|
<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => openDialog({ kind: "agent", name, inst })}>${tn("settingsButton")}</button>
|
|
809
882
|
${st === "running" ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "pause", () => ctx.pauseWake(name, "pause"))}>${label("pause", tn("pause"))}</button>` : null}
|
|
810
883
|
${st === "paused" ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "wake", () => ctx.pauseWake(name, "wake"))}>${label("wake", tn("wake"))}</button>` : null}
|
|
811
|
-
${
|
|
812
|
-
<${Menu} label=${t("app.more")} items=${[{ key: "delete", label: tn("deleteAgentMenu"), icon: "trash", danger: true, disabled: working, onSelect: () => ctx.deleteAgent(name) }]} />
|
|
884
|
+
${["running", "stopped", "crashed"].includes(st) ? html`<button type="button" class="btn btn-sm" disabled=${working} onClick=${() => run(name, "startStop", () => ctx.startStop(name, st === "running"))}>${label("startStop", st === "running" ? tn("stop") : tn("start"))}</button>` : null}
|
|
885
|
+
<${Menu} cls="s-agent-menu" fit=${true} label=${t("app.more")} items=${[{ key: "delete", label: tn("deleteAgentMenu"), icon: "trash", danger: true, disabled: working, onSelect: () => ctx.deleteAgent(name) }]} />
|
|
813
886
|
</span>
|
|
814
887
|
</div>`;
|
|
815
888
|
})}
|
|
816
889
|
</section>`;
|
|
817
|
-
})}</div
|
|
890
|
+
})}</div>`;
|
|
818
891
|
}
|
|
819
892
|
|
|
820
893
|
function ConnectionRetry({ id, ctx }) {
|
|
@@ -844,10 +917,10 @@ function Bots({ ctx, search, openDialog }) {
|
|
|
844
917
|
const all = channelsOf(ctx.fleet);
|
|
845
918
|
const needle = search.trim().toLowerCase();
|
|
846
919
|
const rows = all.map((ch, i) => ({ ch, i })).filter(({ ch }) => !needle || [ch.id, ch.type, ch.group_id, ch.bot_token_env].some((v) => String(v ?? "").toLowerCase().includes(needle)));
|
|
847
|
-
const head = html`<div class="list-head"><span>${all.length === 1 ? tn("countBot") : tn("countBots", all.length)}</span>
|
|
920
|
+
const head = html`<div class="list-head s-list-toolbar"><span>${all.length === 1 ? tn("countBot") : tn("countBots", all.length)}</span>
|
|
848
921
|
<button type="button" id="newBotBtn" class="btn btn-primary" onClick=${() => openDialog({ kind: "newBot" })}><${Icon} name="plus" size=${16} />${tn("newBot")}</button></div>`;
|
|
849
|
-
return html
|
|
850
|
-
${!rows.length ? html
|
|
922
|
+
return html`<section class="card s-chat-connections"><div class="s-chat-section-head"><h3>${layoutText("chatConnections")}</h3>${head}</div>
|
|
923
|
+
${!rows.length ? html`<div class="s-chat-empty"><${Icon} name="plug" size=${22} /><p>${needle ? tn("noAgentMatch", search.trim()) : tn("noBots")}</p></div>` : html`<div class="s-list s-connections-list"><div class="s-list-columns s-connection-columns" aria-hidden="true"><span>${tn("uiConnectionColumnService")}</span><span>${tn("uiConnectionColumnInfo")}</span><span>${tn("uiListColumnActions")}</span></div>${rows.map(({ ch, i }) => {
|
|
851
924
|
const users = (ch.access && ch.access.allowed_users) || [];
|
|
852
925
|
const meta = ctx.connections.find((c, j) => channelId(c, j) === channelId(ch, i)) || {};
|
|
853
926
|
const token = meta.token_present;
|
|
@@ -872,7 +945,7 @@ function Bots({ ctx, search, openDialog }) {
|
|
|
872
945
|
${!overPublicLink && ctx.fleetUp && meta.status !== "connected" ? html`<${ConnectionRetry} id=${channelId(ch, i)} ctx=${ctx} />` : null}
|
|
873
946
|
<button type="button" class="btn btn-sm" onClick=${() => openDialog({ kind: "bot", id: channelId(ch, i) })}>${tn("settingsButton")}</button></span>
|
|
874
947
|
</div>`;
|
|
875
|
-
})}</div>`}
|
|
948
|
+
})}</div>`}</section>`;
|
|
876
949
|
}
|
|
877
950
|
|
|
878
951
|
/**
|
|
@@ -922,40 +995,40 @@ function ProviderKeys({ ctx }) {
|
|
|
922
995
|
} catch { say(spec.id, { error: tn("failed") }); }
|
|
923
996
|
finally { inFlight.current.delete(spec.id); if (lease.current()) setBusy(new Set(inFlight.current)); }
|
|
924
997
|
};
|
|
925
|
-
return html`<section class="card s-provider-keys"><h3>${
|
|
926
|
-
${!ctx.providerSecrets.length ? html`<p class="note">${tn("noProviderVerifiers")}</p>` : ctx.providerSecrets.map((spec) =>
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
998
|
+
return html`<section class="card s-provider-keys s-auth-section"><header class="s-auth-section-head"><div><h3>${layoutText("apiKeysTitle")}</h3><p>${layoutText("apiKeysHint")}</p></div></header>
|
|
999
|
+
${!ctx.providerSecrets.length ? html`<p class="note">${tn("noProviderVerifiers")}</p>` : html`<div class="s-api-key-list">${ctx.providerSecrets.map((spec) => {
|
|
1000
|
+
const provider = spec.id.split(".")[0], mark = ["openai", "anthropic"].includes(provider) ? provider : null;
|
|
1001
|
+
return html`<div key=${spec.id} class="s-key s-api-key-row">
|
|
1002
|
+
<div class="s-api-key-heading"><span class="s-provider-symbol">${mark ? html`<${ProviderMark} provider=${mark} size=${22} />` : html`<${Icon} name="key" size=${22} />`}</span><strong>${spec.display_name}</strong><span class=${`s-auth-state${spec.token_present ? " is-usable" : ""}`}>${spec.token_present ? tn("keyConfigured") : tn("keyNotConfigured")}</span></div>
|
|
1003
|
+
${spec.verifier === "available" ? html`<div class="s-api-key-form"><label><span>${tn("providerKeyInput", spec.display_name)}</span><input type="password" autocomplete="new-password" aria-label=${tn("providerKeyInput", spec.display_name)}
|
|
1004
|
+
placeholder=${layoutText(spec.token_present ? "apiReplacePlaceholder" : "apiNewPlaceholder")} value=${keys[spec.id] || ""} onInput=${(e) => setKeys((k) => ({ ...k, [spec.id]: e.target.value }))} /></label>
|
|
1005
|
+
<button type="button" class="btn btn-sm btn-primary" disabled=${busy.has(spec.id)} onClick=${() => go(spec)}>${tn("verifyApply")}</button></div>`
|
|
1006
|
+
: html`<div class="s-api-key-unsupported"><span class="s-auth-state">${tn("unsupportedVerifier")}</span><p class="note">${tn("unsupportedVerifierHint")}</p></div>`}
|
|
1007
|
+
${notes[spec.id] ? html`<p class=${`feedback${notes[spec.id].error ? " error" : ""}`} role="status">${notes[spec.id].error || notes[spec.id].text}</p>` : null}
|
|
1008
|
+
</div>`;
|
|
1009
|
+
})}</div>`}
|
|
1010
|
+
<p class="note s-api-action-note">${tn("uiProviderKeyActionHint")}</p>
|
|
935
1011
|
</section>`;
|
|
936
1012
|
}
|
|
937
1013
|
|
|
938
1014
|
function Classic({ ctx, search, openDialog }) {
|
|
939
1015
|
const rooms = Object.entries((ctx.classic && ctx.classic.channels) || {}).map(([key, ch]) => ({ key, ...ch }));
|
|
940
|
-
if (!rooms.length) return html
|
|
1016
|
+
if (!rooms.length) return html`<div class="s-chat-empty"><${Icon} name="room" size=${22} /><p>${tn("noClassic")}</p></div>`;
|
|
941
1017
|
const needle = search.trim().toLowerCase();
|
|
942
1018
|
const list = rooms.filter((c) => !needle || String(c.name || "").toLowerCase().includes(needle) || String(c.instanceName || "").toLowerCase().includes(needle))
|
|
943
1019
|
.sort((a, b) => ((STATUS_ORDER[ctx.classicRuntime(a.instanceName).status] ?? 9) - (STATUS_ORDER[ctx.classicRuntime(b.instanceName).status] ?? 9))
|
|
944
1020
|
|| String(a.name || "").localeCompare(String(b.name || "")));
|
|
945
|
-
if (!list.length) return html
|
|
946
|
-
return html`<div class="list-head"><span>${rooms.length === 1 ? tn("countRoom") : tn("countRooms", rooms.length)}</span></div><div class="s-list">${list.map((c) => {
|
|
1021
|
+
if (!list.length) return html`<div class="s-chat-empty"><${Icon} name="search" size=${22} /><p>${tn("noAgentMatch", search.trim())}</p></div>`;
|
|
1022
|
+
return html`<div class="list-head s-list-toolbar"><span>${rooms.length === 1 ? tn("countRoom") : tn("countRooms", rooms.length)}</span></div><div class="s-list s-classic-list"><div class="s-list-columns s-classic-columns" aria-hidden="true"><span>${tn("uiClassicColumnRoom")}</span><span>${tn("uiAgentColumnCli")}</span><span>${tn("uiListColumnState")}</span><span>${tn("uiListColumnActions")}</span></div>${list.map((c) => {
|
|
947
1023
|
const rt = ctx.classicRuntime(c.instanceName);
|
|
948
1024
|
const sum = effectiveSummary(ctx.live[c.instanceName] || {}, c, ctx.fleet.defaults || {}, (ctx.classic && ctx.classic.defaults) || {});
|
|
949
1025
|
const adapter = c.adapterId || "discord";
|
|
950
|
-
return html`<div key=${c.key} class="s-row">
|
|
951
|
-
<span class=${
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
<
|
|
955
|
-
<span class="
|
|
956
|
-
<span class=${`tag${adapter !== "discord" ? " persona" : ""}`}>${adapter}</span>
|
|
957
|
-
${c.collab ? html`<span class="tag">collab</span>` : null}
|
|
958
|
-
<span class="tag">${tn(`exec_${rt.execution}`)}</span>
|
|
1026
|
+
return html`<div key=${c.key} class="s-row s-classic-row">
|
|
1027
|
+
<div class="s-classic-identity"><span class="s-name" title=${c.instanceName || ""}>${shortName(c.name || c.instanceName || "?", { display_name: c.display_name })}</span>
|
|
1028
|
+
<div class="s-agent-context"><span class="tag">${tn("effortTag", sum.effort)}</span><span class=${`tag${adapter !== "discord" ? " persona" : ""}`}>${adapter}</span>${c.collab ? html`<span class="tag">collab</span>` : null}</div>
|
|
1029
|
+
</div>
|
|
1030
|
+
<div class="s-classic-cli"><${CliProductMark} id=${sum.backend} size=${20} /><span><strong>${cliLabel(sum.backend)}</strong><span class="s-meta" title=${sum.model}>${sum.model}</span></span></div>
|
|
1031
|
+
<span class="s-classic-status"><span class=${dotClass(rt.execution)} aria-hidden="true"></span><span>${tn(`exec_${rt.execution}`)}</span></span>
|
|
959
1032
|
<span class="s-actions">
|
|
960
1033
|
<button type="button" class="btn btn-sm" onClick=${() => openDialog({ kind: "classic", room: c })}>${tn("settingsButton")}</button>
|
|
961
1034
|
${rt.status === "running" ? html`<button type="button" class="btn btn-sm" onClick=${() => ctx.pauseWake(c.instanceName, "pause")}>${tn("pause")}</button>` : null}
|
|
@@ -1005,7 +1078,6 @@ function General({ ctx, part = "all" }) {
|
|
|
1005
1078
|
const { schema } = ctx;
|
|
1006
1079
|
const d = ctx.fleet.defaults || {}, c = (ctx.classic && ctx.classic.defaults) || {};
|
|
1007
1080
|
const hang = d.hang_detector || {}, startup = d.startup || {};
|
|
1008
|
-
const primary = channelsOf(ctx.fleet)[0];
|
|
1009
1081
|
const original = useMemo(() => ({ c: structuredClone(c) }), []);
|
|
1010
1082
|
const base = useMemo(() => generalForm(d, c, ctx.fleet, schema), []);
|
|
1011
1083
|
const [f, setF] = useDraft(ctx, "general", () => base);
|
|
@@ -1021,6 +1093,9 @@ function General({ ctx, part = "all" }) {
|
|
|
1021
1093
|
const warnings = { concurrency: f.concurrency.trim() !== "" && num(f.concurrency) > 4 ? "concurrencyWarning" : "", stagger: num(f.stagger) < 100 ? "staggerWarning" : "" };
|
|
1022
1094
|
const ready = !Object.values(errors).some(Boolean);
|
|
1023
1095
|
const firstError = Object.values(errors).find(Boolean);
|
|
1096
|
+
// What saving the edited fields costs (the schema's impact, the agents that set the field themselves): shown under each
|
|
1097
|
+
// edited field, and added up on the Save bar.
|
|
1098
|
+
const notes = sharedNotes({ schema, fleet: ctx.fleet, classic: ctx.classic, classicStatus: (name) => ctx.classicRuntime(name).status, live: ctx.live, fleetUp: ctx.fleetUp, f, base, errors });
|
|
1024
1099
|
// #2347: every edit, staged as it is made (the first render included: a draft kept from before is staged again).
|
|
1025
1100
|
useEffect(() => {
|
|
1026
1101
|
if (!ready) {
|
|
@@ -1067,10 +1142,12 @@ function General({ ctx, part = "all" }) {
|
|
|
1067
1142
|
// that sets it (POST /ui/config; a change to it waits for a fleet admin's OK, as it did there).
|
|
1068
1143
|
const roots = f.roots.map((r) => String(r).trim()).filter(Boolean); // ChipList keeps "2024" as a number; paths are text
|
|
1069
1144
|
syncStage(ctx, "fleet:project_roots", sameValue(roots, base.roots) ? null : { label: tn("projectRootsTitle"), count: 1,
|
|
1070
|
-
impact: impactOf(schema, "fleet.project_roots"),
|
|
1145
|
+
impact: impactOf(schema, "fleet.project_roots"), notes: notes.bar.roots,
|
|
1146
|
+
request: { method: "POST", url: "/ui/config", body: { project_roots: roots } } });
|
|
1071
1147
|
const dKeys = Object.keys(defaultsPatch), cKeys = Object.keys(classicPatch);
|
|
1148
|
+
// The bar says what this Save costs in the page's own words (how many agents restart), not a bare impact label.
|
|
1072
1149
|
syncStage(ctx, "defaults:fleet", dKeys.length ? { label: tn("updateDefaults"), count: dKeys.length,
|
|
1073
|
-
impact: batchImpact(schema, dKeys, (k) => defaultsImpact(schema, k)),
|
|
1150
|
+
impact: batchImpact(schema, dKeys, (k) => defaultsImpact(schema, k)), notes: notes.bar.defaults,
|
|
1074
1151
|
request: { method: "PUT", url: "/api/settings/fleet/defaults", body: defaultsPatch } } : null);
|
|
1075
1152
|
syncStage(ctx, "defaults:classic", cKeys.length ? { label: tn("updateClassicDefaults"), count: cKeys.length,
|
|
1076
1153
|
impact: cKeys.every((k) => impactOf(schema, `classic_defaults.${k}`) === "now") ? "now" : "fleet",
|
|
@@ -1084,39 +1161,17 @@ function General({ ctx, part = "all" }) {
|
|
|
1084
1161
|
log_level: !d.log_level, agent_mode: !d.agent_mode, hangOn: !hasOwn(hang, "enabled"), hang: !hasOwn(hang, "timeout_minutes"),
|
|
1085
1162
|
concurrency: !hasOwn(startup, "concurrency"), stagger: !hasOwn(startup, "stagger_delay_ms"),
|
|
1086
1163
|
};
|
|
1087
|
-
const dm = (k) => (unset[k] && sameValue(f[k], base[k]) ? html`<${DefaultMark} />` : null);
|
|
1088
1164
|
const fromDefaults = (k, value, target) => ({ text: valueText(value), builtin: !hasOwn(d, k), from: inAgentDefaults(target) });
|
|
1089
|
-
const L = (text, field, id
|
|
1165
|
+
const L = (text, field, id) => html`<${Label} text=${text} schema=${schema} field=${field} htmlFor=${id} />`;
|
|
1090
1166
|
const fleetReply = replyGuardSupported(f.backend, f.agent_mode, d.kiro_ui) ? tn("replyGuardSupported") : tn("replyGuardUnsupported", f.backend, f.agent_mode);
|
|
1091
1167
|
const classicReply = replyGuardSupported(f.classicBackend, f.agent_mode, d.kiro_ui) ? tn("replyGuardSupported") : tn("replyGuardUnsupported", f.classicBackend, f.agent_mode);
|
|
1092
1168
|
// #2347: Agent defaults show the fleet's part; Chat & connections ClassicBot's. One form, one draft either way.
|
|
1093
1169
|
const fleetPart = part !== "classic", classicPart = part !== "fleet";
|
|
1094
|
-
return html`<div class=${`form s-general s-part-${part}`}>
|
|
1095
|
-
${fleetPart ? html
|
|
1096
|
-
|
|
1097
|
-
<div class=${fc("field", "locale")}>${L(tn("language"), "defaults.locale", "g-locale", "locale")}<${Select} id="g-locale" value=${f.locale} onChange=${set("locale")}
|
|
1098
|
-
options=${localeOptions(f.locale).map((o) => (o.auto ? { value: "", label: tn("localeAuto") } : o))} /></div>
|
|
1099
|
-
<div class=${fc("field", "backend")}>${L(tn("defaultBackend"), "defaults.backend", "g-be", "backend")}<${BackendSelect} id="g-be" value=${f.backend} onChange=${set("backend")} /></div>
|
|
1100
|
-
<div class=${fc("field", "model")}>${L(tn("defaultModel"), "defaults.model", "g-model", "model")}<${ModelSelect} id="g-model" value=${f.model} onChange=${set("model")}
|
|
1101
|
-
backend=${f.backend || "claude-code"} inherit=${tn("modelCliDefault")} /></div>
|
|
1102
|
-
<div class=${fc("field", "auto")}>${L(`${tn("autoPause")} (${tn("minutes")})`, "defaults.auto_pause_after", "g-auto", "auto")}<input id="g-auto" type="number" min="0" step="1" class=${errors.auto ? "invalid" : ""} value=${f.auto} onInput=${(e) => set("auto")(e.target.value)} /><${Feedback} error=${errors.auto} /></div>
|
|
1103
|
-
<div class=${fc("field", "tool_progress")}>${L(tn("toolProgress"), "defaults.tool_progress", "g-tp", "tool_progress")}<${Select} id="g-tp" value=${f.tool_progress} onChange=${set("tool_progress")} options=${TOOL_PROGRESS} /></div>
|
|
1104
|
-
<div class=${fc("field", "visibility")}>${L(tn("crossInstanceVisibility"), "defaults.cross_instance_visibility", "g-vis", "visibility")}<${Select} id="g-vis" value=${f.visibility} onChange=${set("visibility")} options=${VISIBILITY_MODES} />
|
|
1105
|
-
<p class="note">${tn("crossInstanceVisibilityHint")}</p></div>
|
|
1106
|
-
<div class=${fc("field", "tips")}>${L(tn("dailyTips"), "defaults.tips", "g-tips", "tips")}<${Select} id="g-tips" value=${f.tips} onChange=${set("tips")} options=${noticeChoices()} /><${InEffect} text=${noticeLabel(noticeMode(f.tips))} /><p class="note">${tn("dailyTipsHint")}</p></div>
|
|
1107
|
-
<div class=${fc("field", "replyTriggers")}><label class="check"><input id="g-reply-triggers" type="checkbox" checked=${f.replyTriggers} onChange=${(e) => set("replyTriggers")(e.target.checked)} /><span>${tn("replyTriggers")}</span>${dm("replyTriggers")}<${Impact} schema=${schema} field="defaults.reply_triggers" /></label><p class="note">${tn("replyTriggersHint")}</p></div>
|
|
1108
|
-
<div class=${fc("field", "reply")}><label class="check"><input id="g-reply" type="checkbox" checked=${f.reply} onChange=${(e) => set("reply")(e.target.checked)} /><span>${tn("replyCompletionGuard")}</span>${dm("reply")}<${Impact} schema=${schema} field="defaults.reply_completion_guard" /></label>
|
|
1109
|
-
<p class="note">${fleetReply}</p></div>
|
|
1110
|
-
</div>
|
|
1111
|
-
<fieldset id="g-dash" class=${fc("field dash-perms", ...DASHBOARD_FEATURES.map((k) => `dash_${k}`))}><legend>${L(tn("dashboardAccess"), "defaults.dashboard")}</legend>
|
|
1112
|
-
<p class="note">${tn("dashboardDefaultsHint")}</p>
|
|
1113
|
-
${DASHBOARD_FEATURES.map((k) => html`<label key=${k} class="check"><input type="checkbox" checked=${f[`dash_${k}`]}
|
|
1114
|
-
onChange=${(e) => set(`dash_${k}`)(e.target.checked)} /><span>${tn(`dashboard_${k}`)}</span></label>`)}
|
|
1115
|
-
</fieldset>
|
|
1116
|
-
</section>` : null}
|
|
1117
|
-
${classicPart ? html`<section class="card"><h3>${tn("classicDefaultsTitle")}</h3>
|
|
1170
|
+
return html`<div class=${fleetPart ? "s-defaults-layout" : "s-classic-layout"}><div class=${`form s-general s-part-${part}`}>
|
|
1171
|
+
${fleetPart ? html`<${SharedAgentSettings} ctx=${ctx} form=${{ f, set, base, errors, warnings, unset, fc, notes, replyNote: fleetReply }} />` : null}
|
|
1172
|
+
${classicPart ? html`<section class="card s-classic-defaults-card"><h3>${tn("classicDefaultsTitle")}</h3>
|
|
1118
1173
|
<div class="grid2">
|
|
1119
|
-
<div class=${fc("field", "classicBackend")}>${L(tn("classicBackend"), "classic_defaults.backend", "g-cbe")}<${BackendSelect} id="g-cbe" value=${f.classicBackend} onChange=${set("classicBackend")} />
|
|
1174
|
+
<div class=${fc("field", "classicBackend")}>${L(tn("classicBackend"), "classic_defaults.backend", "g-cbe")}<${BackendSelect} id="g-cbe" value=${f.classicBackend} onChange=${set("classicBackend")} hostOnly />
|
|
1120
1175
|
${!c.backend && f.classicBackend === base.classicBackend ? html`<${Inherited} text=${valueText(f.classicBackend, "backend")} builtin=${!d.backend} from=${inAgentDefaults("#g-be")} />` : null}</div>
|
|
1121
1176
|
<div class=${fc("field", "classicToolProgress", "classicToolProgressInherit")}>${L(tn("toolProgress"), "classic_defaults.tool_progress", "g-ctp")}
|
|
1122
1177
|
<${Override} inherit=${f.classicToolProgressInherit} onInherit=${set("classicToolProgressInherit")} inherited=${fromDefaults("tool_progress", d.tool_progress ?? "off", "#g-tp")}>
|
|
@@ -1135,31 +1190,7 @@ function General({ ctx, part = "all" }) {
|
|
|
1135
1190
|
<div id="g-guilds" class=${fc("field", "guilds")}>${L(tn("allowedGuilds"), "classic.allowed_guilds")}<${ChipList} items=${f.guilds} onChange=${set("guilds")} placeholder=${tn("guildIdPlaceholder")} label=${tn("allowedGuilds")} /></div>
|
|
1136
1191
|
</div>
|
|
1137
1192
|
</section>` : null}
|
|
1138
|
-
|
|
1139
|
-
<p class="note">${tn("projectRootsHint")}</p>
|
|
1140
|
-
<div id="g-roots" class=${fc("field", "roots")}>${L(tn("projectRootsTitle"), "fleet.project_roots")}<${ChipList} items=${f.roots} onChange=${set("roots")} placeholder="/path/to/projects" label=${tn("projectRootsTitle")} />
|
|
1141
|
-
${f.roots.length ? null : html`<${InEffect} text=${tn("projectRootsAnywhere")} />`}</div>
|
|
1142
|
-
</section>` : null}
|
|
1143
|
-
${fleetPart ? html`<${Drawer} title=${tn("advancedSection")}>
|
|
1144
|
-
<section class="card"><h3>${tn("runtimeResources")}</h3><div class="grid2">
|
|
1145
|
-
<div class=${fc("field", "tool_set")}>${L(tn("toolSet"), "defaults.tool_set", "g-ts", "tool_set")}<${Select} id="g-ts" value=${f.tool_set} onChange=${set("tool_set")}
|
|
1146
|
-
options=${[{ value: "", label: tn("toolSetUnset", toolSetDefault({}, {}), toolSetDefault({}, { general_topic: true })) }, ...TOOL_SETS]} /></div>
|
|
1147
|
-
<div class=${fc("field", "log_level")}>${L(tn("logLevel"), "defaults.log_level", "g-ll", "log_level")}<${Select} id="g-ll" value=${f.log_level} onChange=${set("log_level")} options=${LOG_LEVELS} /></div>
|
|
1148
|
-
<div class=${fc("field", "agent_mode")}>${L(tn("agentMode"), "defaults.agent_mode", "g-am", "agent_mode")}<${Select} id="g-am" value=${f.agent_mode} onChange=${set("agent_mode")} options=${AGENT_MODES} /></div>
|
|
1149
|
-
</div></section>
|
|
1150
|
-
<section class="card"><h3>${tn("detection")}</h3><div class="grid2">
|
|
1151
|
-
<label class=${fc("check", "hangOn")}><input id="g-hang-on" type="checkbox" checked=${f.hangOn} onChange=${(e) => set("hangOn")(e.target.checked)} /><span>${tn("hangEnabled")}</span>${dm("hangOn")}<${Impact} schema=${schema} field="defaults.hang_detector" /></label>
|
|
1152
|
-
<div class=${fc("field", "hang")}>${L(`${tn("hangTimeout")} (${tn("minutes")})`, "defaults.hang_detector", "g-hang", "hang")}<input id="g-hang" type="number" min="0.1" step="0.5" class=${errors.hang ? "invalid" : ""} value=${f.hang} onInput=${(e) => set("hang")(e.target.value)} /><${Feedback} error=${errors.hang} /></div>
|
|
1153
|
-
</div></section>
|
|
1154
|
-
<section class="card"><h3>${tn("startup")}</h3><div class="grid2">
|
|
1155
|
-
<div class=${fc("field", "concurrency")}>${L(tn("concurrency"), "fleet.spawn_concurrency", "g-conc")}<input id="g-conc" type="number" min="1" max="20" step="1" class=${errors.concurrency ? "invalid" : ""} value=${f.concurrency} onInput=${(e) => set("concurrency")(e.target.value)} /><${Feedback} error=${errors.concurrency} warning=${warnings.concurrency} />
|
|
1156
|
-
${f.concurrency.trim() === "" ? html`<${InEffect} text=${tn("concurrencyAuto")} />` : null}</div>
|
|
1157
|
-
<div class=${fc("field", "stagger")}>${L(`${tn("staggerDelay")} (ms)`, "fleet.spawn_stagger_ms", "g-stag", "stagger")}<input id="g-stag" type="number" min="0" max="30000" step="100" class=${errors.stagger ? "invalid" : ""} value=${f.stagger} onInput=${(e) => set("stagger")(e.target.value)} /><${Feedback} error=${errors.stagger} warning=${warnings.stagger} /></div>
|
|
1158
|
-
</div></section>
|
|
1159
|
-
<section class="card"><h3>${tn("accessTitle")}</h3>
|
|
1160
|
-
<p class="note">${primary ? tn("accessMovedHint", primary.id || chLabel(0)) : tn("noBots")}</p></section>
|
|
1161
|
-
</${Drawer}>` : null}
|
|
1162
|
-
</div>`;
|
|
1193
|
+
</div></div>`;
|
|
1163
1194
|
}
|
|
1164
1195
|
|
|
1165
1196
|
/**
|
|
@@ -1199,6 +1230,7 @@ export function uploadMbInEffect(web) {
|
|
|
1199
1230
|
}
|
|
1200
1231
|
function WebSection({ ctx, staged, part = "all" }) {
|
|
1201
1232
|
const { schema } = ctx;
|
|
1233
|
+
const [accessTab, setAccessTab] = useSettingsTabs("access", "login");
|
|
1202
1234
|
const web = ctx.fleet.web || {}, local = (web.session && web.session.local) || {}, term = ctx.fleet.web_terminal || {};
|
|
1203
1235
|
// Over the public link the fields read only; the Guests and Web authority cards are not offered (the server never
|
|
1204
1236
|
// serves their reads there).
|
|
@@ -1210,13 +1242,14 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1210
1242
|
usagePub: web.usage_report_on_public_link === true, // #2122: off by default
|
|
1211
1243
|
levels: web.office_levels !== false, // #2661: on by default
|
|
1212
1244
|
cdn: web.preview_cdn === true, // #2911 (7): off by default
|
|
1245
|
+
loginQr: web.login_qr === true, // #3061 (P2b): off by default
|
|
1213
1246
|
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 },
|
|
1214
1247
|
session: { absolute_hours: local.absolute_hours ?? null, idle_hours: local.idle_hours ?? null },
|
|
1215
1248
|
terminal: { enabled: term.enabled ?? null, ttl_minutes: term.ttl_minutes ?? null },
|
|
1216
1249
|
}), []);
|
|
1217
1250
|
const text = (v) => (v === null || v === undefined ? "" : String(v));
|
|
1218
1251
|
/** #2347: a field's row class: `s-dirty` while it differs from what is saved (the draft may come from before). */
|
|
1219
|
-
const savedForm = useMemo(() => ({ notify: String(original.notify), echo: original.echo, log: original.log, usagePub: original.usagePub, levels: original.levels, cdn: original.cdn, pub: original.pub.allow_public,
|
|
1252
|
+
const savedForm = useMemo(() => ({ notify: String(original.notify), echo: original.echo, log: original.log, usagePub: original.usagePub, levels: original.levels, cdn: original.cdn, loginQr: original.loginQr, pub: original.pub.allow_public,
|
|
1220
1253
|
ttl: String(original.pub.ttl_minutes), protocol: original.pub.protocol, hostname: original.pub.hostname, originPort: String(original.pub.origin_port),
|
|
1221
1254
|
abs: text(original.session.absolute_hours), idle: text(original.session.idle_hours), termOn: original.terminal.enabled !== false,
|
|
1222
1255
|
termTtl: text(original.terminal.ttl_minutes), autoOpen: original.pub.auto_open }), []);
|
|
@@ -1230,7 +1263,7 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1230
1263
|
return {
|
|
1231
1264
|
notify: String(pick(pending, "notify_login", original.notify)),
|
|
1232
1265
|
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),
|
|
1233
|
-
levels: pick(pending, "office_levels", original.levels), cdn: pick(pending, "preview_cdn", original.cdn),
|
|
1266
|
+
levels: pick(pending, "office_levels", original.levels), cdn: pick(pending, "preview_cdn", original.cdn), loginQr: pick(pending, "login_qr", original.loginQr),
|
|
1234
1267
|
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),
|
|
1235
1268
|
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),
|
|
1236
1269
|
abs: text(pick(session, "absolute_hours", original.session.absolute_hours)), idle: text(pick(session, "idle_hours", original.session.idle_hours)),
|
|
@@ -1284,6 +1317,7 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1284
1317
|
...(f.usagePub !== original.usagePub ? { usage_report_on_public_link: f.usagePub } : {}),
|
|
1285
1318
|
...(f.levels !== original.levels ? { office_levels: f.levels } : {}),
|
|
1286
1319
|
...(f.cdn !== original.cdn ? { preview_cdn: f.cdn } : {}),
|
|
1320
|
+
...(f.loginQr !== original.loginQr ? { login_qr: f.loginQr } : {}),
|
|
1287
1321
|
...(Object.keys(publicPatch).length ? { public_link: publicPatch } : {}),
|
|
1288
1322
|
...(Object.keys(sessionPatch).length ? { session: { local: sessionPatch } } : {}),
|
|
1289
1323
|
...(Object.keys(terminalPatch).length ? { web_terminal: terminalPatch } : {}),
|
|
@@ -1295,6 +1329,7 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1295
1329
|
...(body.usage_report_on_public_link !== undefined ? ["web.usage_report_on_public_link"] : []),
|
|
1296
1330
|
...(body.office_levels !== undefined ? ["web.office_levels"] : []),
|
|
1297
1331
|
...(body.preview_cdn !== undefined ? ["web.preview_cdn"] : []),
|
|
1332
|
+
...(body.login_qr !== undefined ? ["web.login_qr"] : []),
|
|
1298
1333
|
...Object.keys(publicPatch).map((k) => `web.public_link.${k}`),
|
|
1299
1334
|
...Object.keys(sessionPatch).map((k) => `web.session.local.${k}`),
|
|
1300
1335
|
...Object.keys(terminalPatch).map((k) => `web_terminal.${k}`),
|
|
@@ -1329,17 +1364,35 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1329
1364
|
if (v === undefined) return html`${roText(webReadOnlyDefault(path, ctx.fleet))} <${DefaultMark} />${capped ? html` <span class="tag">${tn("cappedByTotal")}</span>` : null}`;
|
|
1330
1365
|
return applies === v ? roText(v) : html`${roText(v)} <span class="tag">${tn("inEffectShort", roText(applies))}</span>`;
|
|
1331
1366
|
};
|
|
1332
|
-
//
|
|
1333
|
-
//
|
|
1334
|
-
// usage over the public link), Advanced (what only fleet.yaml sets).
|
|
1367
|
+
// One Web draft remains mounted across the Access tabs. A tab only changes what is visible;
|
|
1368
|
+
// validation, confirmation and staged writes continue to belong to the existing form.
|
|
1335
1369
|
const has = (p) => part === "all" || part === p;
|
|
1336
1370
|
const lock = (body) => html`<fieldset class="s-web-fields" disabled=${overPublicLink}>${body}</fieldset>`;
|
|
1371
|
+
const tabs = [
|
|
1372
|
+
{ id: "login", label: layoutText("accessLogin") },
|
|
1373
|
+
{ id: "guests", label: layoutText("accessGuests") },
|
|
1374
|
+
{ id: "sharing", label: layoutText("accessSharing") },
|
|
1375
|
+
];
|
|
1376
|
+
const toggleRow = (key, id, label, hint, impact) => html`<div class=${fc("s-setting-row", key)}>
|
|
1377
|
+
<div class="s-setting-copy"><label for=${id}>${part === "dashboard" ? layoutText(`revDashboard_${key}`) : tn(label)}<${Impact} schema=${schema} field=${impact} /></label>
|
|
1378
|
+
<p class="note" id=${`${id}-hint`}>${part === "dashboard" ? layoutText(`revDashboardHint_${key}`) : tn(hint)}</p>
|
|
1379
|
+
${part === "dashboard" ? html`<details class="s-setting-details"><summary>${layoutText("revDetails")}</summary><p class="note"><strong>${tn(label)}</strong> ${tn(hint)}</p></details>` : null}
|
|
1380
|
+
</div>
|
|
1381
|
+
<input class="s-ui-toggle" id=${id} type="checkbox" checked=${f[key]} aria-describedby=${`${id}-hint`} onChange=${(e) => set(key)(e.target.checked)} />
|
|
1382
|
+
</div>`;
|
|
1383
|
+
const configured = (path) => { const [top, key] = path.split("."); return (top === "web" ? web : term)[key] !== undefined; };
|
|
1337
1384
|
return html`<div class=${`form s-web s-part-${part}`}>
|
|
1338
|
-
${
|
|
1339
|
-
${
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1385
|
+
${overPublicLink && part !== "readonly" ? html`<p class="note s-access-notice" role="status" id="webPublicRefused">${tn("webPublicRefused")}</p>` : null}
|
|
1386
|
+
${has("access") ? html`<${SettingsTabs} id="access" value=${accessTab} onChange=${setAccessTab} items=${tabs} />
|
|
1387
|
+
<div class="s-access-banner"><${Icon} name="info" size=${18} /><p>${layoutText("revAccessPolicy")}</p><details class="s-access-policy"><summary>${layoutText("revDetails")}</summary><p class="note">${tn("webLead")}</p></details></div>
|
|
1388
|
+
<${SettingsTabPanel} group="access" id="login" active=${accessTab === "login"}>
|
|
1389
|
+
<div class="s-access-login-layout"><div class="s-access-stack">
|
|
1390
|
+
${/* #3008: a web-only fleet's connections from outside — changed on this computer only, shown (read-only) elsewhere. */ ""}
|
|
1391
|
+
<${OutsideCard} />
|
|
1392
|
+
${/* Refs #3061 (P2a): sign a new device in with its 8-character code — approved here by the verified owner. */ ""}
|
|
1393
|
+
<${DevicesCard} />
|
|
1394
|
+
${lock(html`<section class="card s-access-session"><h3>${layoutText("revLoginSessions")}</h3>
|
|
1395
|
+
<div class=${fc("field", "notify")}><label for="webNotifyLogin">${tn("webNotifyLogin")}<${Impact} schema=${schema} field="web.notify_login" /></label><${Select} id="webNotifyLogin" value=${f.notify} onChange=${set("notify")} options=${noticeChoices()} /><${InEffect} text=${noticeLabel(noticeMode(f.notify))} /></div>
|
|
1343
1396
|
<div class="grid2">
|
|
1344
1397
|
<div class=${fc("field", "abs")}><label for="webSessionAbsolute">${tn("sessionAbsolute")}</label><input id="webSessionAbsolute" type="number" min="1" max="720" step="any"
|
|
1345
1398
|
class=${errors.abs ? "invalid" : ""} value=${f.abs} onInput=${(e) => set("abs")(e.target.value)} /><${Feedback} error=${errors.abs} />
|
|
@@ -1348,8 +1401,16 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1348
1401
|
class=${errors.idle ? "invalid" : ""} value=${f.idle} onInput=${(e) => set("idle")(e.target.value)} /><${Feedback} error=${errors.idle} />
|
|
1349
1402
|
${value(f.idle) === null && !errors.abs ? html`<${InEffect} text=${tn("hoursValue", idle)} why=${idle < 48 ? tn("cappedBySession") : null} />` : null}</div>
|
|
1350
1403
|
</div>
|
|
1351
|
-
</
|
|
1352
|
-
|
|
1404
|
+
<p class="note s-session-ceiling">${layoutText("revPublicSessionLimit")}</p>
|
|
1405
|
+
${/* Refs #3061 (P2b): the QR code on a new device's sign-in page (a web-only fleet's "Sign in with another device"). */ ""}
|
|
1406
|
+
<label class=${fc("check", "loginQr")}><input id="webLoginQr" type="checkbox" checked=${f.loginQr} aria-describedby="webLoginQr-hint" onChange=${(e) => set("loginQr")(e.target.checked)} /><span>${tn("webLoginQr")}</span><${Impact} schema=${schema} field="web.login_qr" /></label>
|
|
1407
|
+
<p class="note" id="webLoginQr-hint">${tn("webLoginQrHint")}</p>
|
|
1408
|
+
<details class="s-setting-details"><summary>${layoutText("revSessionDetails")}</summary><p class="note">${tn("webSessionHint")}</p><p class="note">${tn("webNotifyLoginHint")}</p></details>
|
|
1409
|
+
</section>`)}
|
|
1410
|
+
${!overPublicLink ? html`<${WebAuthorityCard} ctx=${ctx} staged=${staged} />` : null}
|
|
1411
|
+
${!overPublicLink ? html`<${HubCardSlot} />` : null}
|
|
1412
|
+
${!overPublicLink && ctx.fleet.hub?.hubId ? html`<${HubRetentionSlot} /><${HubBrowserCertificateSlot} />` : null}
|
|
1413
|
+
<details class="drawer s-terminal-disclosure"><summary>${tn("webTerminalTitle")}</summary><div class="drawer-body">${lock(html`<section class="card s-access-terminal"><h3>${tn("webTerminalTitle")}</h3>
|
|
1353
1414
|
<p class="note">${tn("webTerminalHint")}</p>
|
|
1354
1415
|
<label class=${fc("check", "termOn")}><input id="webTerminalEnabled" type="checkbox" checked=${f.termOn} onChange=${(e) => set("termOn")(e.target.checked)} /><span>${tn("webTerminalEnabled")}</span><${Impact} schema=${schema} field="web_terminal.enabled" /></label>
|
|
1355
1416
|
<div class="grid2">
|
|
@@ -1357,8 +1418,18 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1357
1418
|
class=${errors.termTtl ? "invalid" : ""} value=${f.termTtl} onInput=${(e) => set("termTtl")(e.target.value)} /><${Feedback} error=${errors.termTtl} />
|
|
1358
1419
|
${value(f.termTtl) === null ? html`<${InEffect} text=${tn("minutesValue", 10)} />` : null}</div>
|
|
1359
1420
|
</div>
|
|
1360
|
-
</section>
|
|
1361
|
-
|
|
1421
|
+
</section>`)}</div></details>
|
|
1422
|
+
</div><aside class="card s-access-related"><h3>${layoutText("revRelatedAccess")}</h3>
|
|
1423
|
+
<button type="button" onClick=${() => setAccessTab("guests")}><${Icon} name="user" size=${18} /><span><strong>${layoutText("accessGuests")}</strong><small>${layoutText("revRelatedGuests")}</small></span><${Icon} name="chevron" size=${16} /></button>
|
|
1424
|
+
<button type="button" onClick=${() => setAccessTab("sharing")}><${Icon} name="globe" size=${18} /><span><strong>${layoutText("accessSharing")}</strong><small>${layoutText("revRelatedSharing")}</small></span><${Icon} name="chevron" size=${16} /></button>
|
|
1425
|
+
</aside></div>
|
|
1426
|
+
</${SettingsTabPanel}>
|
|
1427
|
+
<${SettingsTabPanel} group="access" id="guests" active=${accessTab === "guests"}>
|
|
1428
|
+
${!overPublicLink ? html`<${GuestsCard} ctx=${ctx} staged=${staged} />` : html`<p class="note">${tn("webPublicRefused")}</p>`}
|
|
1429
|
+
</${SettingsTabPanel}>
|
|
1430
|
+
<${SettingsTabPanel} group="access" id="sharing" active=${accessTab === "sharing"}>
|
|
1431
|
+
<div class="s-access-stack">
|
|
1432
|
+
${lock(html`<section class="card s-public-entry"><h3>${layoutText("revPublicEntry")}</h3>
|
|
1362
1433
|
<label class=${fc("check", "pub")}><input id="publicWebLink" type="checkbox" checked=${f.pub} onChange=${(e) => set("pub")(e.target.checked)} /><span>${tn("publicLink")}</span><${Impact} schema=${schema} field="web.public_link.allow_public" /></label>
|
|
1363
1434
|
<p class="note">${tn("publicLinkHint")}</p>
|
|
1364
1435
|
<div class="grid2">
|
|
@@ -1374,35 +1445,31 @@ function WebSection({ ctx, staged, part = "all" }) {
|
|
|
1374
1445
|
${named ? html`<p class="note" id="publicTtlNamedHint">${tn("publicTtlNamedHint")}</p>` : null}
|
|
1375
1446
|
${named || f.autoOpen ? html`<label class=${fc("check", "autoOpen")}><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>
|
|
1376
1447
|
<p class="note">${tn("publicAutoOpenHint")}</p><${Feedback} error=${errors.autoOpen} />` : null}
|
|
1448
|
+
|
|
1449
|
+
${!overPublicLink ? html`<div class="s-public-credentials"><${PublicTunnelToken} /></div>` : null}
|
|
1450
|
+
</section>`)}
|
|
1451
|
+
<div class="s-sharing-list"><h3>${layoutText("revReadOnlySharing")}</h3><p class="note">${layoutText("revSharingOrigin")}</p><${OfficeSharesCard} /><${PageSharesCard} /></div>
|
|
1452
|
+
</div>
|
|
1453
|
+
</${SettingsTabPanel}>` : null}
|
|
1454
|
+
${has("chat") ? lock(html`<section class="card s-web-chat"><h3>${layoutText("messageBehavior")}</h3>
|
|
1455
|
+
${toggleRow("echo", "webEchoToChannel", "webEcho", "webEchoHint", "web.echo_to_channel")}
|
|
1377
1456
|
</section>`) : null}
|
|
1378
|
-
${has("
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
${has("access") ? html`<${OutsideCard} />` : null}
|
|
1384
|
-
${has("chat") ? lock(html`<section class="card"><h3>${tn("webChat")}</h3>
|
|
1385
|
-
<label class=${fc("check", "echo")}><input id="webEchoToChannel" type="checkbox" checked=${f.echo} onChange=${(e) => set("echo")(e.target.checked)} /><span>${tn("webEcho")}</span><${Impact} schema=${schema} field="web.echo_to_channel" /></label>
|
|
1386
|
-
<p class="note">${tn("webEchoHint")}</p>
|
|
1387
|
-
</section>`) : null}
|
|
1388
|
-
${has("dashboard") ? lock(html`<section class="card"><h3>${tn("webDashboardTitle")}</h3>
|
|
1389
|
-
<label class=${fc("check", "log")}><input id="webLogTab" type="checkbox" checked=${f.log} onChange=${(e) => set("log")(e.target.checked)} /><span>${tn("webLogTab")}</span><${Impact} schema=${schema} field="web.log_tab" /></label>
|
|
1390
|
-
<p class="note">${tn("webLogTabHint")}</p>
|
|
1391
|
-
<label class=${fc("check", "usagePub")}><input id="webUsagePublic" type="checkbox" checked=${f.usagePub} onChange=${(e) => set("usagePub")(e.target.checked)} /><span>${tn("webUsagePublic")}</span><${Impact} schema=${schema} field="web.usage_report_on_public_link" /></label>
|
|
1392
|
-
<p class="note">${tn("webUsagePublicHint")}</p>
|
|
1393
|
-
<label class=${fc("check", "levels")}><input id="webOfficeLevels" type="checkbox" checked=${f.levels} onChange=${(e) => set("levels")(e.target.checked)} /><span>${tn("webOfficeLevels")}</span><${Impact} schema=${schema} field="web.office_levels" /></label>
|
|
1394
|
-
<p class="note">${tn("webOfficeLevelsHint")}</p>
|
|
1395
|
-
<label class=${fc("check", "cdn")}><input id="webPreviewCdn" type="checkbox" checked=${f.cdn} onChange=${(e) => set("cdn")(e.target.checked)} /><span>${tn("webPreviewCdn")}</span><${Impact} schema=${schema} field="web.preview_cdn" /></label>
|
|
1396
|
-
<p class="note">${tn("webPreviewCdnHint")}</p>
|
|
1457
|
+
${has("dashboard") ? lock(html`<section class="card s-dashboard-features"><h3>${layoutText("dashboardFeatures")}</h3>
|
|
1458
|
+
${toggleRow("log", "webLogTab", "webLogTab", "webLogTabHint", "web.log_tab")}
|
|
1459
|
+
${toggleRow("usagePub", "webUsagePublic", "webUsagePublic", "webUsagePublicHint", "web.usage_report_on_public_link")}
|
|
1460
|
+
${toggleRow("levels", "webOfficeLevels", "webOfficeLevels", "webOfficeLevelsHint", "web.office_levels")}
|
|
1461
|
+
${toggleRow("cdn", "webPreviewCdn", "webPreviewCdn", "webPreviewCdnHint", "web.preview_cdn")}
|
|
1397
1462
|
</section>`) : null}
|
|
1398
|
-
${has("readonly") ? html`<
|
|
1399
|
-
<
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1463
|
+
${has("readonly") ? html`<div class="s-effective-view"><p class="s-effective-notice"><${Icon} name="info" size=${18} />${layoutText("revEffectiveHint")}</p>
|
|
1464
|
+
<section class="card s-web-readonly"><h3 class="sr-only">${tn("webReadOnlyTitle")}</h3>
|
|
1465
|
+
<div class="s-ro-columns" aria-hidden="true"><span>${layoutText("effectiveKey")}</span><span>${layoutText("effectiveValue")}</span><span>${layoutText("effectiveSource")}</span></div>
|
|
1466
|
+
${["web", "web_terminal"].map(group => html`<h4 class="s-ro-group">${group === "web" ? tn("sec_web-dashboard") : tn("webTerminalTitle")}</h4>
|
|
1467
|
+
<dl class="s-web-ro">${WEB_READ_ONLY.filter(k => k.startsWith(`${group}.`)).map((k) => html`<div key=${k}><dt><code>${k}</code></dt><dd class="s-ro-value">${shown(k)}</dd><dd class="s-ro-source" aria-label=${layoutText("effectiveSource")}><span class="tag">${layoutText(configured(k) ? "effectiveSourceConfig" : "effectiveSourceDefault")}</span></dd></div>`)}</dl>`)}
|
|
1468
|
+
</section><div class="s-effective-footnotes"><p class="note">${tn("webReadOnlyLead")}</p><p class="note">${tn("webSearchHint")}</p></div>
|
|
1469
|
+
<div class="s-effective-actions"><button type="button" class="btn" onClick=${() => revealSettingsTarget(document.getElementById("advanced-panel-editor"))}><${Icon} name="edit" size=${16} />${layoutText("revGoEditor")}</button></div>
|
|
1470
|
+
</div>` : null}
|
|
1403
1471
|
</div>`;
|
|
1404
1472
|
}
|
|
1405
|
-
|
|
1406
1473
|
/**
|
|
1407
1474
|
* Developer: the fleet model as YAML or JSON, to read, copy, download — or edit. #2347: an edit's Apply stages its
|
|
1408
1475
|
* writes in the Save bar like every form's change (Save writes them, in order, then one apply; Discard drops them),
|
|
@@ -1456,14 +1523,15 @@ function Developer({ ctx }) {
|
|
|
1456
1523
|
return html`<section class="card s-dev">
|
|
1457
1524
|
<div class="s-dev-bar">
|
|
1458
1525
|
<div class="seg-inline" role="group" aria-label=${tn("format")}>
|
|
1459
|
-
${["yaml", "json"].map((k) => html`<button key=${k} type="button" class=${`btn btn-sm${fmt === k ? " on" : ""}`} aria-pressed=${fmt === k ? "true" : "false"} onClick=${() => setFmt(k)}>${k.toUpperCase()}</button>`)}</div>
|
|
1460
|
-
<button type="button" class="btn btn-sm" disabled=${blocked && !editing} title=${blocked && !editing ? tn("devFormsUnsaved") : undefined} onClick=${() => setEditing(!editing)}>${editing ? tn("viewMode") : tn("editMode")}</button>
|
|
1526
|
+
${["yaml", "json"].map((k) => html`<button key=${k} type="button" class=${`btn btn-sm${fmt === k ? " on" : ""}`} aria-pressed=${fmt === k ? "true" : "false"} onClick=${() => setFmt(k)}>${k.toUpperCase()}</button>`)}</div><p class="s-dev-context"><${Icon} name="info" size=${15} />${layoutText("revEditorContext")}</p>
|
|
1527
|
+
<div class="s-dev-actions"><button type="button" class="btn btn-sm" disabled=${blocked && !editing} title=${blocked && !editing ? tn("devFormsUnsaved") : undefined} onClick=${() => setEditing(!editing)}>${editing ? tn("viewMode") : tn("editMode")}</button>
|
|
1461
1528
|
<button type="button" class="btn btn-sm" title=${tn("copy")} onClick=${copy}><${Icon} name="copy" size=${14} /><span class="lbl">${tn("copy")}</span></button>
|
|
1462
|
-
<button type="button" class="btn btn-sm" title=${tn("devDownload")} onClick=${download}><${Icon} name="download" size=${14} /><span class="lbl">${tn("devDownload")}</span></button>
|
|
1529
|
+
<button type="button" class="btn btn-sm" title=${tn("devDownload")} onClick=${download}><${Icon} name="download" size=${14} /><span class="lbl">${tn("devDownload")}</span></button></div>
|
|
1463
1530
|
</div>
|
|
1464
1531
|
${editing ? html`<textarea class="s-yaml" aria-label=${tn("devEditor")} spellcheck=${false} wrap="off" value=${draft} onInput=${(e) => setDraft(e.target.value)}></textarea>
|
|
1465
1532
|
<div class="save-row"><button type="button" class="btn btn-primary" disabled=${blocked} onClick=${save}>${tn("devApply")}</button><span class="note">${tn("devApplyHint")}</span></div>`
|
|
1466
|
-
: html`<pre class="s-yaml">${text}</pre>`}
|
|
1533
|
+
: html`<pre class="s-yaml" tabindex="0">${text}</pre>`}
|
|
1534
|
+
<div class="s-dev-state"><span class="s-dev-file">fleet.yaml</span><${Icon} name=${editing ? "edit" : "view"} size=${14} /><span>${layoutText(editing ? "developerEditing" : "developerReadOnly")}</span></div>
|
|
1467
1535
|
${blocked ? html`<p class="note s-dev-blocked" role="status">${tn("devFormsUnsaved")}</p>`
|
|
1468
1536
|
: held && !msg ? html`<p class="note s-dev-held" role="status">${tn("devStaged", heldCount)}</p>` : null}
|
|
1469
1537
|
${msg ? html`<p class=${`feedback${msg.error ? " error" : ""}`} role="status">${msg.error || msg.text}</p>` : null}
|
|
@@ -1476,16 +1544,23 @@ function Developer({ ctx }) {
|
|
|
1476
1544
|
*/
|
|
1477
1545
|
function PendingBar({ staged, busy, onApply, onDiscard, section }) {
|
|
1478
1546
|
const changes = [...staged.values()];
|
|
1479
|
-
|
|
1547
|
+
// What Save will cost, one line each: a change that knows its own words (the shared agent settings: how many agents
|
|
1548
|
+
// restart) says them; any other says its impact label.
|
|
1549
|
+
const costs = [];
|
|
1550
|
+
for (const c of changes) {
|
|
1551
|
+
if (c.invalid) continue;
|
|
1552
|
+
for (const line of Array.isArray(c.notes) && c.notes.length ? c.notes : [impactText(c.impact)]) if (!costs.includes(line)) costs.push(line);
|
|
1553
|
+
}
|
|
1480
1554
|
const invalid = changes.filter((c) => c.invalid).length;
|
|
1481
1555
|
// #2382 review: a field to fix in another section is named, and the message goes there (its field focused).
|
|
1482
1556
|
const elsewhere = changes.find((c) => c.invalid && c.section && c.section !== section);
|
|
1557
|
+
const problem = elsewhere || changes.find((c) => c.invalid && c.target);
|
|
1483
1558
|
const count = changes.reduce((n, c) => n + (Number.isInteger(c.count) && c.count > 0 ? c.count : 1), 0);
|
|
1484
1559
|
return html`<div data-trust="panel-controls" class="s-pending" role="region" aria-label=${tn("pendingRegion")}>
|
|
1485
1560
|
<strong>${tn("changesPending", count)}</strong>
|
|
1486
|
-
<span class="note">${
|
|
1561
|
+
<span class="note">${costs.join(" · ")}</span>
|
|
1487
1562
|
<span class="s-pending-actions">
|
|
1488
|
-
${!invalid ? null :
|
|
1563
|
+
${!invalid ? null : problem ? html`<button type="button" class="link-btn feedback error s-fix" role="status" onClick=${() => goToTarget(problem.section || section, problem.target)}>${elsewhere ? tn("fixToSaveIn", invalid, tn(`sec_${elsewhere.section}`)) : tn("fixToSave", invalid)}</button>`
|
|
1489
1564
|
: html`<span class="feedback error s-fix" role="status">${tn("fixToSave", invalid)}</span>`}
|
|
1490
1565
|
<button type="button" class="btn" onClick=${onDiscard} disabled=${busy}>${tn("discard")}</button>
|
|
1491
1566
|
<button type="button" class="btn btn-primary" onClick=${onApply} disabled=${busy || invalid > 0} title=${busy ? tn("applyBusyLocal") : undefined}>${tn("applyChanges")}</button>
|
|
@@ -1592,12 +1667,11 @@ function PublicTunnelToken() {
|
|
|
1592
1667
|
} catch { if (lease.current()) setMessage(tn("applyFailed")); }
|
|
1593
1668
|
finally { inFlight.current = false; if (lease.current()) setBusy(false); }
|
|
1594
1669
|
};
|
|
1595
|
-
return html`<section class="card"><h3>${tn("namedToken")}</h3>
|
|
1670
|
+
return html`<section class="card s-tunnel-token"><div class="s-token-head"><h3>${tn("namedToken")}</h3><span class="tag">${present ? tn("keyConfigured") : tn("keyNotConfigured")}</span></div>
|
|
1596
1671
|
<p class="note">${tn("namedTokenHint")}</p>
|
|
1597
|
-
<
|
|
1598
|
-
<
|
|
1599
|
-
<button type="button" class="btn btn-sm" disabled=${busy || !
|
|
1600
|
-
<button type="button" class="btn btn-sm" disabled=${busy || !present} onClick=${() => go(true)}>${tn("namedTokenClear")}</button>
|
|
1672
|
+
<details class="s-token-editor"><summary>${layoutText(present ? "revUpdateCredential" : "revSetCredential")}</summary><div class="s-token-editor-body"><input class="s-token-input" id="publicTunnelToken" type="password" autocomplete="new-password" aria-label=${tn("namedToken")} value=${secret} onInput=${e => { setSecret(e.target.value); setTypedTunnelToken(e.target.value); }} />
|
|
1673
|
+
<div class="s-token-actions"><button type="button" class="btn btn-sm" disabled=${busy || !secret} onClick=${() => go(false)}>${tn("namedTokenSet")}</button>
|
|
1674
|
+
<button type="button" class="btn btn-sm" disabled=${busy || !present} onClick=${() => go(true)}>${tn("namedTokenClear")}</button></div></div></details>
|
|
1601
1675
|
${message ? html`<p class="note" role="status">${message}</p>` : null}
|
|
1602
1676
|
</section>`;
|
|
1603
1677
|
}
|