@songsid/agend 2.3.0-beta.2 → 2.3.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/README.zh-TW.md +7 -1
- package/dist/agent-cli-instructions.md +9 -2
- package/dist/agent-cli.js +63 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +4 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-file-read.d.ts +4 -1
- package/dist/agent-file-read.js +189 -16
- package/dist/agent-file-read.js.map +1 -1
- package/dist/agent-whats-new.d.ts +11 -0
- package/dist/agent-whats-new.js +29 -5
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.d.ts +30 -1
- package/dist/auth-api.js +45 -13
- package/dist/auth-api.js.map +1 -1
- package/dist/authority/authority-state.d.ts +38 -0
- package/dist/authority/authority-state.js +114 -0
- package/dist/authority/authority-state.js.map +1 -0
- package/dist/authority/session-authorizations.d.ts +43 -0
- package/dist/authority/session-authorizations.js +102 -0
- package/dist/authority/session-authorizations.js.map +1 -0
- package/dist/authority/web-authority.d.ts +120 -0
- package/dist/authority/web-authority.js +157 -0
- package/dist/authority/web-authority.js.map +1 -0
- package/dist/backend/claude-code.d.ts +2 -2
- package/dist/backend/claude-code.js +18 -8
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +8 -0
- package/dist/backend/codex-metadata.js +74 -17
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.js +15 -2
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/credential-profile.d.ts +2 -0
- package/dist/backend/credential-profile.js +2 -0
- package/dist/backend/credential-profile.js.map +1 -1
- package/dist/backend/types.d.ts +6 -0
- package/dist/backend/types.js +15 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-availability.d.ts +120 -0
- package/dist/backend-availability.js +396 -0
- package/dist/backend-availability.js.map +1 -0
- package/dist/backend-command.d.ts +23 -3
- package/dist/backend-command.js +25 -4
- package/dist/backend-command.js.map +1 -1
- package/dist/bug-report-cli.d.ts +30 -0
- package/dist/bug-report-cli.js +138 -0
- package/dist/bug-report-cli.js.map +1 -0
- package/dist/bug-report.d.ts +47 -0
- package/dist/bug-report.js +136 -0
- package/dist/bug-report.js.map +1 -0
- package/dist/bundled-skills.d.ts +14 -0
- package/dist/bundled-skills.js +29 -0
- package/dist/bundled-skills.js.map +1 -0
- package/dist/cache-ledger.d.ts +16 -3
- package/dist/cache-ledger.js +33 -13
- package/dist/cache-ledger.js.map +1 -1
- package/dist/cache-service.d.ts +55 -3
- package/dist/cache-service.js +152 -16
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord-client-retirement.d.ts +5 -0
- package/dist/channel/adapters/discord-client-retirement.js +57 -0
- package/dist/channel/adapters/discord-client-retirement.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +9 -0
- package/dist/channel/adapters/discord.js +49 -4
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/mcp-tools.js +22 -11
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/types.d.ts +6 -0
- package/dist/classic-channel-manager.d.ts +10 -5
- package/dist/classic-channel-manager.js +12 -9
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +224 -111
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +6 -0
- package/dist/config-validator.js +129 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +13 -1
- package/dist/config.js +14 -5
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-notice.d.ts +7 -0
- package/dist/cross-instance-notice.js +10 -0
- package/dist/cross-instance-notice.js.map +1 -1
- package/dist/daemon.d.ts +24 -1
- package/dist/daemon.js +151 -19
- package/dist/daemon.js.map +1 -1
- package/dist/decision-list.d.ts +25 -0
- package/dist/decision-list.js +30 -0
- package/dist/decision-list.js.map +1 -0
- package/dist/delivery-outbox.d.ts +10 -0
- package/dist/delivery-outbox.js +17 -1
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/diagnostic-redaction.d.ts +10 -0
- package/dist/diagnostic-redaction.js +167 -0
- package/dist/diagnostic-redaction.js.map +1 -0
- package/dist/fleet-context.d.ts +10 -0
- package/dist/fleet-manager.d.ts +505 -15
- package/dist/fleet-manager.js +1870 -204
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-process-handlers.d.ts +18 -0
- package/dist/fleet-process-handlers.js +69 -0
- package/dist/fleet-process-handlers.js.map +1 -0
- package/dist/fleet-traffic.d.ts +74 -0
- package/dist/fleet-traffic.js +196 -0
- package/dist/fleet-traffic.js.map +1 -0
- package/dist/general-knowledge/skills/bug-report/SKILL.md +31 -0
- package/dist/general-knowledge/skills/credential-profiles/SKILL.md +17 -6
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +6 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +2 -0
- package/dist/general-knowledge/skills/multi-channel/SKILL.md +3 -2
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +1 -1
- package/dist/general-knowledge/skills/scheduling/SKILL.md +4 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +190 -47
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +545 -0
- package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +1 -1
- package/dist/human-delivery-receipts.d.ts +24 -1
- package/dist/human-delivery-receipts.js +64 -11
- package/dist/human-delivery-receipts.js.map +1 -1
- package/dist/instance-config-impact.js +7 -1
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -1
- package/dist/instance-lifecycle.js +79 -18
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instance-names.d.ts +4 -0
- package/dist/instance-names.js +12 -0
- package/dist/instance-names.js.map +1 -0
- package/dist/instructions.d.ts +12 -1
- package/dist/instructions.js +13 -2
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +173 -12
- package/dist/locale.js.map +1 -1
- package/dist/log-steps.d.ts +1 -0
- package/dist/log-steps.js +15 -0
- package/dist/log-steps.js.map +1 -1
- package/dist/login-controller.d.ts +45 -0
- package/dist/login-controller.js +101 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/ls-attach-resolve.d.ts +96 -0
- package/dist/ls-attach-resolve.js +180 -0
- package/dist/ls-attach-resolve.js.map +1 -0
- package/dist/ls-rows.d.ts +12 -0
- package/dist/ls-rows.js +82 -3
- package/dist/ls-rows.js.map +1 -1
- package/dist/memory-hogs.d.ts +27 -0
- package/dist/memory-hogs.js +124 -0
- package/dist/memory-hogs.js.map +1 -0
- package/dist/needs-you.d.ts +10 -0
- package/dist/needs-you.js +2 -1
- package/dist/needs-you.js.map +1 -1
- package/dist/outbound-handlers.d.ts +11 -0
- package/dist/outbound-handlers.js +139 -11
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +200 -4
- package/dist/outbound-schemas.js +124 -11
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +17 -4
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +9 -0
- package/dist/public-web-link.js +8 -0
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +19 -1
- package/dist/quickstart-api.js +94 -4
- package/dist/quickstart-api.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +4 -0
- package/dist/reply-buttons-controller.js +2 -2
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/restart-progress.d.ts +80 -1
- package/dist/restart-progress.js +306 -21
- package/dist/restart-progress.js.map +1 -1
- package/dist/rollout-index.d.ts +5 -0
- package/dist/rollout-index.js +26 -5
- package/dist/rollout-index.js.map +1 -1
- package/dist/scheduler/db.d.ts +40 -13
- package/dist/scheduler/db.js +123 -89
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/task-board-text.d.ts +26 -0
- package/dist/scheduler/task-board-text.js +135 -0
- package/dist/scheduler/task-board-text.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +650 -0
- package/dist/scheduler/task-board.js +1938 -0
- package/dist/scheduler/task-board.js.map +1 -0
- package/dist/scheduler/types.d.ts +6 -1
- package/dist/search/search-docs.d.ts +58 -0
- package/dist/search/search-docs.js +63 -0
- package/dist/search/search-docs.js.map +1 -0
- package/dist/search/search-index.d.ts +141 -0
- package/dist/search/search-index.js +440 -0
- package/dist/search/search-index.js.map +1 -0
- package/dist/search/search-store.d.ts +122 -0
- package/dist/search/search-store.js +236 -0
- package/dist/search/search-store.js.map +1 -0
- package/dist/search/search-worker.d.ts +1 -0
- package/dist/search/search-worker.js +163 -0
- package/dist/search/search-worker.js.map +1 -0
- package/dist/service-installer.js +12 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.d.ts +23 -0
- package/dist/settings-api.js +164 -3
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +104 -0
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +3 -1
- package/dist/settings-confirmation.js +2 -0
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +34 -3
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.d.ts +11 -0
- package/dist/settings-http-confirmation.js +10 -0
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +23 -7
- package/dist/setup-form.js.map +1 -1
- package/dist/spawn-gate.d.ts +1 -0
- package/dist/spawn-gate.js +13 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/task-board-tool.d.ts +25 -0
- package/dist/task-board-tool.js +154 -0
- package/dist/task-board-tool.js.map +1 -0
- package/dist/task-board-waker.d.ts +44 -0
- package/dist/task-board-waker.js +128 -0
- package/dist/task-board-waker.js.map +1 -0
- package/dist/tmux-exec-helper.d.ts +94 -0
- package/dist/tmux-exec-helper.js +407 -0
- package/dist/tmux-exec-helper.js.map +1 -0
- package/dist/tmux-manager.d.ts +5 -0
- package/dist/tmux-manager.js +42 -11
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.d.ts +0 -7
- package/dist/tool-permissions.js +44 -5
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +17 -1
- package/dist/topic-commands.js +45 -19
- package/dist/topic-commands.js.map +1 -1
- package/dist/tunnel/cloudflared.js +37 -2
- package/dist/tunnel/cloudflared.js.map +1 -1
- package/dist/tunnel/types.d.ts +3 -1
- package/dist/tunnel/types.js.map +1 -1
- package/dist/types.d.ts +63 -1
- package/dist/ui/app-effects.js +90 -32
- package/dist/ui/backend-signin.js +297 -0
- package/dist/ui/chat-ambient.js +307 -0
- package/dist/ui/chat-effect-posters.js +8 -8
- package/dist/ui/chat-effects.js +110 -15
- package/dist/ui/chat-msg-actions.js +176 -0
- package/dist/ui/chat-render.js +21 -3
- package/dist/ui/chat-store.js +64 -12
- package/dist/ui/chat-strings.js +85 -8
- package/dist/ui/chat-thread.js +204 -21
- package/dist/ui/effect-trial-controller.js +13 -8
- package/dist/ui/effect-trial-panel.js +19 -16
- package/dist/ui/effects-waker.js +70 -0
- package/dist/ui/fleet-canvas-layout.js +117 -0
- package/dist/ui/fleet-canvas.js +555 -0
- package/dist/ui/fleet-org.js +27 -12
- package/dist/ui/fleet-route-scene.js +207 -0
- package/dist/ui/fleet-route-worker.js +21 -0
- package/dist/ui/fleet-route.js +88 -0
- package/dist/ui/fleet-task-card.js +436 -0
- package/dist/ui/fleet-task-common.js +448 -0
- package/dist/ui/fleet-tasks.js +535 -0
- package/dist/ui/fleet-traffic.js +359 -0
- package/dist/ui/fleet-usage.js +435 -0
- package/dist/ui/panel-chat.js +264 -66
- package/dist/ui/panel-details.js +2 -1
- package/dist/ui/panel-fleet.js +65 -83
- package/dist/ui/panel-needs.js +4 -2
- package/dist/ui/panel-settings.js +56 -11
- package/dist/ui/preview.js +3 -2
- package/dist/ui/search-dialog.js +349 -0
- package/dist/ui/settings-appearance.js +44 -19
- package/dist/ui/settings-apply.js +3 -3
- package/dist/ui/settings-catalog.js +92 -0
- package/dist/ui/settings-confirm.js +7 -2
- package/dist/ui/settings-dialogs.js +40 -12
- package/dist/ui/settings-effects.js +4 -3
- package/dist/ui/settings-guests.js +117 -0
- package/dist/ui/settings-learn.js +25 -0
- package/dist/ui/settings-model.js +15 -6
- package/dist/ui/settings-mods.js +23 -9
- package/dist/ui/settings-owner-effects.js +15 -13
- package/dist/ui/settings-strings.js +122 -42
- package/dist/ui/settings-web-authority.js +91 -0
- package/dist/ui/shared/agend-auth.js +1 -1
- package/dist/ui/shared/app-i18n.js +11 -2
- package/dist/ui/shared/app-prefs.js +17 -4
- package/dist/ui/shared/app-route.js +19 -1
- package/dist/ui/shared/app-session.js +2 -0
- package/dist/ui/shared/app-shell.js +174 -30
- package/dist/ui/shared/app-store.js +26 -1
- package/dist/ui/shared/app-stream.js +5 -1
- package/dist/ui/shared/app-themes.js +140 -7
- package/dist/ui/shared/app.css +704 -20
- package/dist/ui/shared/app.js +26 -15
- package/dist/ui/shared/card-strings.js +8 -0
- package/dist/ui/shared/effect-app-runtime.js +68 -19
- package/dist/ui/shared/effect-chat-runtime.js +16 -3
- package/dist/ui/shared/effect-frame.js +26 -7
- package/dist/ui/shared/effect-geometry.js +24 -9
- package/dist/ui/shared/effect-owner-source.js +8 -1
- package/dist/ui/shared/effect-policy.js +21 -7
- package/dist/ui/shared/effect-profiler.js +31 -9
- package/dist/ui/shared/effect-registry.js +97 -50
- package/dist/ui/shared/effect-stock-snapshot.js +9 -0
- package/dist/ui/shared/effect-stock-trust.js +62 -10
- package/dist/ui/shared/effect-trial-shadow.js +62 -0
- package/dist/ui/shared/effect-trial-source.js +1 -1
- package/dist/ui/shared/effect-trial-stage.js +54 -31
- package/dist/ui/shared/effect-trial.css +40 -0
- package/dist/ui/shared/fx-motion.js +67 -0
- package/dist/ui/shared/identity-card.js +100 -11
- package/dist/ui/shared/identity-color.js +14 -10
- package/dist/ui/shared/instance-nav.js +179 -23
- package/dist/ui/shared/owner-css.js +30 -1
- package/dist/ui/shared/panel-view.js +24 -4
- package/dist/ui/shared/tokens.css +9 -3
- package/dist/ui/shared/ui-icons.js +2 -0
- package/dist/ui/shared/ui-menu.js +20 -7
- package/dist/ui/shared/ui-toast.js +16 -3
- package/dist/ui/shared/usage-dialog.js +34 -3
- package/dist/ui/shared/view-strings.js +72 -0
- package/dist/ui/shared/web-authorize.js +198 -0
- package/dist/ui/web-terminal/terminal.css +4 -4
- package/dist/ui/web-terminal/terminal.html +1 -1
- package/dist/update-launch.d.ts +9 -0
- package/dist/update-launch.js +38 -12
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/format-rich.js +6 -3
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +2 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/i18n.d.ts +13 -1
- package/dist/usage/i18n.js +29 -0
- package/dist/usage/i18n.js.map +1 -1
- package/dist/usage/providers.d.ts +81 -2
- package/dist/usage/providers.js +240 -38
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.d.ts +5 -1
- package/dist/usage/usage-api.js +184 -58
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/usage-report.d.ts +158 -0
- package/dist/usage-report.js +226 -0
- package/dist/usage-report.js.map +1 -0
- package/dist/usage-rollup.d.ts +51 -0
- package/dist/usage-rollup.js +168 -0
- package/dist/usage-rollup.js.map +1 -0
- package/dist/user-systemd.d.ts +24 -0
- package/dist/user-systemd.js +75 -0
- package/dist/user-systemd.js.map +1 -0
- package/dist/view-api.d.ts +39 -0
- package/dist/view-api.js +69 -6
- package/dist/view-api.js.map +1 -1
- package/dist/web-ambient.d.ts +72 -0
- package/dist/web-ambient.js +161 -0
- package/dist/web-ambient.js.map +1 -0
- package/dist/web-api.d.ts +98 -14
- package/dist/web-api.js +1027 -83
- package/dist/web-api.js.map +1 -1
- package/dist/web-appearance-policy.d.ts +4 -6
- package/dist/web-appearance-policy.js +5 -12
- package/dist/web-appearance-policy.js.map +1 -1
- package/dist/web-appearance-tools.d.ts +3 -0
- package/dist/web-appearance-tools.js +22 -3
- package/dist/web-appearance-tools.js.map +1 -1
- package/dist/web-appearance-view.d.ts +27 -2
- package/dist/web-appearance-view.js +129 -14
- package/dist/web-appearance-view.js.map +1 -1
- package/dist/web-appearance.d.ts +17 -3
- package/dist/web-appearance.js +85 -8
- package/dist/web-appearance.js.map +1 -1
- package/dist/web-asset-parts.d.ts +2 -2
- package/dist/web-asset-parts.js +3 -3
- package/dist/web-asset-parts.js.map +1 -1
- package/dist/web-auth.js +3 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-backend-login.d.ts +130 -0
- package/dist/web-backend-login.js +225 -0
- package/dist/web-backend-login.js.map +1 -0
- package/dist/web-card.d.ts +14 -0
- package/dist/web-card.js +40 -6
- package/dist/web-card.js.map +1 -1
- package/dist/web-channel-echo.d.ts +7 -1
- package/dist/web-channel-echo.js +6 -2
- package/dist/web-channel-echo.js.map +1 -1
- package/dist/web-chat-history.d.ts +83 -0
- package/dist/web-chat-history.js +137 -5
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +6 -1
- package/dist/web-commands.js +1 -1
- package/dist/web-commands.js.map +1 -1
- package/dist/web-effect-bootstrap.d.ts +12 -0
- package/dist/web-effect-bootstrap.js +49 -0
- package/dist/web-effect-bootstrap.js.map +1 -0
- package/dist/web-effect-bundle.js +46 -1
- package/dist/web-effect-bundle.js.map +1 -1
- package/dist/web-effect-playback.d.ts +30 -0
- package/dist/web-effect-playback.js +71 -0
- package/dist/web-effect-playback.js.map +1 -0
- package/dist/web-effect-profiles.d.ts +4 -4
- package/dist/web-effect-service.d.ts +11 -4
- package/dist/web-effect-service.js +25 -4
- package/dist/web-effect-service.js.map +1 -1
- package/dist/web-effect-tools.d.ts +1 -0
- package/dist/web-effect-tools.js +4 -4
- package/dist/web-effect-tools.js.map +1 -1
- package/dist/web-effect-trials.d.ts +2 -2
- package/dist/web-effect-trials.js +3 -3
- package/dist/web-effect-trials.js.map +1 -1
- package/dist/web-effect-upload.js +1 -1
- package/dist/web-effect-upload.js.map +1 -1
- package/dist/web-effect-worker.d.ts +1 -1
- package/dist/web-effect-worker.js +2 -2
- package/dist/web-effect-worker.js.map +1 -1
- package/dist/web-effect.d.ts +1 -1
- package/dist/web-guest-access.d.ts +126 -0
- package/dist/web-guest-access.js +238 -0
- package/dist/web-guest-access.js.map +1 -0
- package/dist/web-guest-rooms.d.ts +82 -0
- package/dist/web-guest-rooms.js +135 -0
- package/dist/web-guest-rooms.js.map +1 -0
- package/dist/web-host-guard.d.ts +11 -0
- package/dist/web-host-guard.js +11 -0
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-identity-color.d.ts +1 -1
- package/dist/web-identity-color.js +2 -2
- package/dist/web-identity-color.js.map +1 -1
- package/dist/web-identity-palette.d.ts +1 -1
- package/dist/web-identity-palette.js +2 -2
- package/dist/web-identity-palette.js.map +1 -1
- package/dist/web-image-meta.d.ts +13 -0
- package/dist/web-image-meta.js +62 -0
- package/dist/web-image-meta.js.map +1 -1
- package/dist/web-libavoid.d.ts +14 -0
- package/dist/web-libavoid.js +46 -0
- package/dist/web-libavoid.js.map +1 -0
- package/dist/web-login.d.ts +47 -0
- package/dist/web-login.js +115 -0
- package/dist/web-login.js.map +1 -1
- package/dist/web-mod-agent.d.ts +1 -1
- package/dist/web-mod-agent.js +7 -5
- package/dist/web-mod-agent.js.map +1 -1
- package/dist/web-mod-bundle.d.ts +9 -1
- package/dist/web-mod-bundle.js +62 -3
- package/dist/web-mod-bundle.js.map +1 -1
- package/dist/web-mod-export.d.ts +9 -0
- package/dist/web-mod-export.js +21 -0
- package/dist/web-mod-export.js.map +1 -1
- package/dist/web-mod-store.d.ts +7 -1
- package/dist/web-mod-store.js +19 -6
- package/dist/web-mod-store.js.map +1 -1
- package/dist/web-owner-css-store.d.ts +44 -1
- package/dist/web-owner-css-store.js +70 -9
- package/dist/web-owner-css-store.js.map +1 -1
- package/dist/web-prefs.d.ts +14 -0
- package/dist/web-prefs.js +37 -4
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-preview.d.ts +6 -2
- package/dist/web-preview.js +4 -2
- package/dist/web-preview.js.map +1 -1
- package/dist/web-returning-device.d.ts +41 -0
- package/dist/web-returning-device.js +57 -5
- package/dist/web-returning-device.js.map +1 -1
- package/dist/web-session-authorization.d.ts +132 -0
- package/dist/web-session-authorization.js +193 -0
- package/dist/web-session-authorization.js.map +1 -0
- package/dist/web-session.d.ts +70 -10
- package/dist/web-session.js +137 -22
- package/dist/web-session.js.map +1 -1
- package/dist/web-settings-patch.d.ts +49 -2
- package/dist/web-settings-patch.js +145 -1
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/web-settings-tools.d.ts +94 -0
- package/dist/web-settings-tools.js +301 -0
- package/dist/web-settings-tools.js.map +1 -0
- package/dist/web-shell-routes.d.ts +1 -1
- package/dist/web-shell-routes.js +1 -1
- package/dist/web-shell-routes.js.map +1 -1
- package/dist/web-terminal-http.js +15 -2
- package/dist/web-terminal-http.js.map +1 -1
- package/dist/web-theme-store.d.ts +39 -0
- package/dist/web-theme-store.js +122 -11
- package/dist/web-theme-store.js.map +1 -1
- package/dist/web-theme.d.ts +31 -0
- package/dist/web-theme.js +99 -2
- package/dist/web-theme.js.map +1 -1
- package/dist/web-upload.d.ts +13 -0
- package/dist/web-upload.js +39 -3
- package/dist/web-upload.js.map +1 -1
- package/dist/windows-shortcuts.d.ts +78 -0
- package/dist/windows-shortcuts.js +203 -0
- package/dist/windows-shortcuts.js.map +1 -0
- package/dist/workflow-templates/default.md +4 -1
- package/dist/yaml-shared-nodes.d.ts +25 -0
- package/dist/yaml-shared-nodes.js +185 -0
- package/dist/yaml-shared-nodes.js.map +1 -0
- package/launcher/agend-install.cjs +553 -0
- package/launcher/install-admission.cjs +4 -39
- package/launcher/postinstall.cjs +14 -12
- package/package.json +4 -2
- package/scripts/preinstall-guard.cjs +2 -5
- package/templates/windows-shortcuts.ps1 +181 -0
- package/launcher/old-updater-note.cjs +0 -48
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2293: the global search's index — `search.db`, a derived store of its own (SQLite FTS5, trigram tokenizer).
|
|
3
|
+
*
|
|
4
|
+
* Synchronous (better-sqlite3); it runs in the search worker (search-worker.ts), never on the fleet's loop. Tests use it
|
|
5
|
+
* directly. What is indexed is masked first (maskSecrets, the Log tab's), and only the fields the docs below carry.
|
|
6
|
+
*
|
|
7
|
+
* Queries: every term of 3+ characters is an FTS5 trigram MATCH (a substring, any script — no word breaking needed for
|
|
8
|
+
* Chinese or Japanese); a term of 1–2 characters cannot use a trigram index, so it is an `instr()` filter on rows the
|
|
9
|
+
* other terms or the filters already narrowed. A query of short terms only scans the newest SHORT_SCAN_ROWS rows that
|
|
10
|
+
* match the filters (newest first) and says so (`limited`).
|
|
11
|
+
*/
|
|
12
|
+
import Database from "better-sqlite3";
|
|
13
|
+
import { maskOpenSecretTail, maskSecrets } from "../log-steps.js";
|
|
14
|
+
export const SEARCH_SOURCES = ["chat", "xmsg", "task"];
|
|
15
|
+
export const QUERY_MAX_CHARS = 200;
|
|
16
|
+
export const QUERY_MAX_TERMS = 8;
|
|
17
|
+
export const RESULT_MAX = 200;
|
|
18
|
+
export const SHORT_SCAN_ROWS = 5000;
|
|
19
|
+
export const ROW_CAP = 300_000;
|
|
20
|
+
export const TEXT_MAX = 16_000;
|
|
21
|
+
/**
|
|
22
|
+
* Masking reads this much past TEXT_MAX before the text is cut (#2295 review): a secret cut at the edge loses what makes
|
|
23
|
+
* it recognisable (a closing quote), so the cut comes after the mask. One starting in the kept text and shorter than
|
|
24
|
+
* this is masked whole — a private key block is a few KB. A text cut before it got here (the web chat's history keeps
|
|
25
|
+
* 16000 characters) can end inside a quoted secret: its open tail is masked too (maskOpenSecretTail).
|
|
26
|
+
*/
|
|
27
|
+
export const MASK_MARGIN = 16_000;
|
|
28
|
+
const SCHEMA_VERSION = "1";
|
|
29
|
+
const SNIPPET_BEFORE = 60, SNIPPET_AFTER = 120;
|
|
30
|
+
/** The terms of a query: whitespace-split, lower-cased, deduplicated; long (3+ characters) and short ones apart. */
|
|
31
|
+
export function parseQuery(q) {
|
|
32
|
+
const terms = [...new Set(String(q ?? "").slice(0, QUERY_MAX_CHARS).toLowerCase().split(/\s+/).filter(Boolean))].slice(0, QUERY_MAX_TERMS);
|
|
33
|
+
const len = (t) => [...t].length;
|
|
34
|
+
return { long: terms.filter(t => len(t) >= 3), short: terms.filter(t => len(t) < 3) };
|
|
35
|
+
}
|
|
36
|
+
/** An FTS5 query that matches `term` as a literal substring (a phrase; its quotes doubled). */
|
|
37
|
+
const phrase = (term) => `"${term.replace(/"/g, '""')}"`;
|
|
38
|
+
/** The sentence around the first hit of any term, and every hit's place in it. */
|
|
39
|
+
export function snippetOf(text, terms) {
|
|
40
|
+
const lower = text.toLowerCase();
|
|
41
|
+
let first = -1;
|
|
42
|
+
for (const t of terms) {
|
|
43
|
+
const i = lower.indexOf(t);
|
|
44
|
+
if (i >= 0 && (first < 0 || i < first))
|
|
45
|
+
first = i;
|
|
46
|
+
}
|
|
47
|
+
const from = first < 0 ? 0 : Math.max(0, first - SNIPPET_BEFORE);
|
|
48
|
+
const to = Math.min(text.length, (first < 0 ? 0 : first) + SNIPPET_AFTER + SNIPPET_BEFORE);
|
|
49
|
+
const lead = from > 0 ? "…" : "", tail = to < text.length ? "…" : "";
|
|
50
|
+
const body = text.slice(from, to).replace(/\s+/g, " ");
|
|
51
|
+
const snippet = lead + body + tail;
|
|
52
|
+
const marks = [];
|
|
53
|
+
const lb = snippet.toLowerCase();
|
|
54
|
+
for (const t of terms)
|
|
55
|
+
for (let i = lb.indexOf(t); i >= 0; i = lb.indexOf(t, i + t.length))
|
|
56
|
+
marks.push([i, i + t.length]);
|
|
57
|
+
marks.sort((a, b) => a[0] - b[0]);
|
|
58
|
+
const merged = [];
|
|
59
|
+
for (const m of marks) {
|
|
60
|
+
const last = merged.at(-1);
|
|
61
|
+
if (last && m[0] <= last[1])
|
|
62
|
+
last[1] = Math.max(last[1], m[1]);
|
|
63
|
+
else
|
|
64
|
+
merged.push([...m]);
|
|
65
|
+
}
|
|
66
|
+
return { snippet, marks: merged };
|
|
67
|
+
}
|
|
68
|
+
export class SearchStore {
|
|
69
|
+
db;
|
|
70
|
+
constructor(path) {
|
|
71
|
+
this.db = new Database(path);
|
|
72
|
+
this.db.pragma("journal_mode = WAL");
|
|
73
|
+
this.db.pragma("synchronous = NORMAL");
|
|
74
|
+
this.db.pragma("busy_timeout = 1000");
|
|
75
|
+
this.db.exec(`
|
|
76
|
+
CREATE TABLE IF NOT EXISTS meta(k TEXT PRIMARY KEY, v TEXT NOT NULL);
|
|
77
|
+
CREATE TABLE IF NOT EXISTS docs(
|
|
78
|
+
rowid INTEGER PRIMARY KEY, key TEXT NOT NULL UNIQUE, source TEXT NOT NULL, instance TEXT NOT NULL, peer TEXT,
|
|
79
|
+
sender TEXT NOT NULL, role TEXT, mine TEXT, ts INTEGER NOT NULL, ref TEXT NOT NULL, text TEXT NOT NULL);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS docs_ts ON docs(ts);
|
|
81
|
+
CREATE INDEX IF NOT EXISTS docs_instance_ts ON docs(instance, ts);
|
|
82
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS docs_fts USING fts5(text, sender, content='docs', content_rowid='rowid', tokenize='trigram');
|
|
83
|
+
CREATE TRIGGER IF NOT EXISTS docs_ai AFTER INSERT ON docs BEGIN
|
|
84
|
+
INSERT INTO docs_fts(rowid, text, sender) VALUES (new.rowid, new.text, new.sender); END;
|
|
85
|
+
CREATE TRIGGER IF NOT EXISTS docs_ad AFTER DELETE ON docs BEGIN
|
|
86
|
+
INSERT INTO docs_fts(docs_fts, rowid, text, sender) VALUES ('delete', old.rowid, old.text, old.sender); END;
|
|
87
|
+
CREATE TRIGGER IF NOT EXISTS docs_au AFTER UPDATE ON docs BEGIN
|
|
88
|
+
INSERT INTO docs_fts(docs_fts, rowid, text, sender) VALUES ('delete', old.rowid, old.text, old.sender);
|
|
89
|
+
INSERT INTO docs_fts(rowid, text, sender) VALUES (new.rowid, new.text, new.sender); END;`);
|
|
90
|
+
}
|
|
91
|
+
/** Whether this index was built (backfilled) under the current schema; false on a new or older one. */
|
|
92
|
+
built() {
|
|
93
|
+
const row = this.db.prepare("SELECT v FROM meta WHERE k = 'schema'").get();
|
|
94
|
+
return row?.v === SCHEMA_VERSION && !!this.db.prepare("SELECT v FROM meta WHERE k = 'built_at'").get();
|
|
95
|
+
}
|
|
96
|
+
/** Marks a finished backfill (a rebuild starts over: everything is replaced or added by key). */
|
|
97
|
+
markBuilt(now) {
|
|
98
|
+
const set = this.db.prepare("INSERT INTO meta(k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v");
|
|
99
|
+
this.db.transaction(() => { set.run("schema", SCHEMA_VERSION); set.run("built_at", String(now)); })();
|
|
100
|
+
}
|
|
101
|
+
/** Add or replace docs (by key), in one transaction. Text is masked, one-spaced at its edges and bounded. */
|
|
102
|
+
add(docs) {
|
|
103
|
+
const put = this.db.prepare(`INSERT INTO docs(key, source, instance, peer, sender, role, mine, ts, ref, text)
|
|
104
|
+
VALUES (@key, @source, @instance, @peer, @sender, @role, @mine, @ts, @ref, @text)
|
|
105
|
+
ON CONFLICT(key) DO UPDATE SET source = excluded.source, instance = excluded.instance, peer = excluded.peer,
|
|
106
|
+
sender = excluded.sender, role = excluded.role, mine = excluded.mine, ts = excluded.ts, ref = excluded.ref, text = excluded.text`);
|
|
107
|
+
let n = 0;
|
|
108
|
+
this.db.transaction(() => {
|
|
109
|
+
for (const d of docs) {
|
|
110
|
+
if (!valid(d))
|
|
111
|
+
continue;
|
|
112
|
+
put.run({ key: d.key, source: d.source, instance: d.instance, peer: d.peer ?? null, sender: d.sender.slice(0, 256), role: d.role ?? null,
|
|
113
|
+
mine: d.mine ?? null, ts: Math.trunc(d.ts), ref: JSON.stringify(d.ref ?? {}), text: indexedText(d.text) });
|
|
114
|
+
n++;
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
117
|
+
return n;
|
|
118
|
+
}
|
|
119
|
+
/** An instance's docs go (the instance was deleted). */
|
|
120
|
+
/**
|
|
121
|
+
* An instance removed from the fleet: its chat goes, as the fleet forgets it. Its cross-instance messages and tasks
|
|
122
|
+
* stay — the outbox and the Task Board still hold them, and the other side's view of them is not this instance's.
|
|
123
|
+
*/
|
|
124
|
+
removeInstance(instance) {
|
|
125
|
+
return this.db.prepare("DELETE FROM docs WHERE source = 'chat' AND instance = ?").run(instance).changes;
|
|
126
|
+
}
|
|
127
|
+
/** Docs older than `cutoff` go, then the oldest beyond `cap`; in chunks (the caller yields between calls). */
|
|
128
|
+
prune(cutoff, cap = ROW_CAP, chunk = 1000) {
|
|
129
|
+
let removed = this.db.prepare("DELETE FROM docs WHERE rowid IN (SELECT rowid FROM docs WHERE ts < ? ORDER BY ts LIMIT ?)").run(cutoff, chunk).changes;
|
|
130
|
+
if (removed < chunk) {
|
|
131
|
+
const count = this.db.prepare("SELECT count(*) AS n FROM docs").get().n;
|
|
132
|
+
if (count > cap)
|
|
133
|
+
removed += this.db.prepare("DELETE FROM docs WHERE rowid IN (SELECT rowid FROM docs ORDER BY ts LIMIT ?)").run(Math.min(chunk, count - cap)).changes;
|
|
134
|
+
}
|
|
135
|
+
return { removed, more: removed >= chunk };
|
|
136
|
+
}
|
|
137
|
+
count() { return this.db.prepare("SELECT count(*) AS n FROM docs").get().n; }
|
|
138
|
+
/** The newest matches, newest first. */
|
|
139
|
+
search(f) {
|
|
140
|
+
const { long, short } = parseQuery(f.q);
|
|
141
|
+
if (!long.length && !short.length)
|
|
142
|
+
return { hits: [], limited: false };
|
|
143
|
+
const limit = Math.max(1, Math.min(RESULT_MAX, Math.trunc(f.limit ?? 50)));
|
|
144
|
+
const where = [], args = [];
|
|
145
|
+
if (f.instances?.length) {
|
|
146
|
+
const marks = f.instances.map(() => "?").join(",");
|
|
147
|
+
where.push(`(d.instance IN (${marks}) OR (d.source = 'xmsg' AND d.peer IN (${marks})))`);
|
|
148
|
+
args.push(...f.instances, ...f.instances);
|
|
149
|
+
}
|
|
150
|
+
if (f.sources?.length) {
|
|
151
|
+
where.push(`d.source IN (${f.sources.map(() => "?").join(",")})`);
|
|
152
|
+
args.push(...f.sources);
|
|
153
|
+
}
|
|
154
|
+
if (typeof f.since === "number") {
|
|
155
|
+
where.push("d.ts >= ?");
|
|
156
|
+
args.push(f.since);
|
|
157
|
+
}
|
|
158
|
+
if (typeof f.until === "number") {
|
|
159
|
+
where.push("d.ts < ?");
|
|
160
|
+
args.push(f.until);
|
|
161
|
+
}
|
|
162
|
+
if (f.mine?.length) {
|
|
163
|
+
where.push(`d.mine IN (${f.mine.map(() => "?").join(",")})`);
|
|
164
|
+
args.push(...f.mine);
|
|
165
|
+
}
|
|
166
|
+
if (f.hidden?.length) {
|
|
167
|
+
const marks = f.hidden.map(() => "?").join(",");
|
|
168
|
+
where.push(`NOT (d.source = 'xmsg' AND (d.instance IN (${marks}) OR d.peer IN (${marks})))`);
|
|
169
|
+
args.push(...f.hidden, ...f.hidden);
|
|
170
|
+
}
|
|
171
|
+
if (f.xmsgAmong) {
|
|
172
|
+
const marks = f.xmsgAmong.map(() => "?").join(",");
|
|
173
|
+
where.push(f.xmsgAmong.length ? `(d.source <> 'xmsg' OR (d.instance IN (${marks}) AND d.peer IN (${marks})))` : "d.source <> 'xmsg'");
|
|
174
|
+
args.push(...f.xmsgAmong, ...f.xmsgAmong);
|
|
175
|
+
}
|
|
176
|
+
const shortWhere = short.map(() => "instr(lower(d.text || ' ' || d.sender), ?) > 0");
|
|
177
|
+
let rows, limited = false;
|
|
178
|
+
if (long.length) {
|
|
179
|
+
const sql = `SELECT d.* FROM docs_fts JOIN docs d ON d.rowid = docs_fts.rowid WHERE docs_fts MATCH ?
|
|
180
|
+
${[...where, ...shortWhere].map(w => `AND ${w}`).join(" ")} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
|
|
181
|
+
rows = this.db.prepare(sql).all(long.map(phrase).join(" "), ...args, ...short, limit);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// Short terms only: the newest SHORT_SCAN_ROWS rows the filters allow, scanned.
|
|
185
|
+
const scan = `SELECT * FROM docs d ${where.length ? `WHERE ${where.join(" AND ")}` : ""} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
|
|
186
|
+
const sql = `SELECT * FROM (${scan}) AS d WHERE ${shortWhere.join(" AND ")} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
|
|
187
|
+
rows = this.db.prepare(sql).all(...args, SHORT_SCAN_ROWS, ...short, limit);
|
|
188
|
+
const scanned = this.db.prepare(`SELECT count(*) AS n FROM (${scan}) AS d`).get(...args, SHORT_SCAN_ROWS).n;
|
|
189
|
+
limited = scanned >= SHORT_SCAN_ROWS;
|
|
190
|
+
}
|
|
191
|
+
const terms = [...long, ...short];
|
|
192
|
+
return { hits: rows.map(r => ({ ...hitOf(r), ...snippetOf(r.text, terms) })), limited };
|
|
193
|
+
}
|
|
194
|
+
/** One doc by key, with (for a chat message) up to `around` messages of its chat before and after it. */
|
|
195
|
+
context(key, around = 8) {
|
|
196
|
+
const row = this.db.prepare("SELECT * FROM docs WHERE key = ?").get(key);
|
|
197
|
+
if (!row)
|
|
198
|
+
return null;
|
|
199
|
+
const full = (r) => ({ ...hitOf(r), snippet: "", marks: [], text: r.text });
|
|
200
|
+
if (row.source !== "chat")
|
|
201
|
+
return { doc: full(row), before: [], after: [] };
|
|
202
|
+
const before = this.db.prepare(`SELECT * FROM docs WHERE source = 'chat' AND instance = ? AND (ts < ? OR (ts = ? AND rowid < ?))
|
|
203
|
+
ORDER BY ts DESC, rowid DESC LIMIT ?`).all(row.instance, row.ts, row.ts, row.rowid, around).reverse();
|
|
204
|
+
const after = this.db.prepare(`SELECT * FROM docs WHERE source = 'chat' AND instance = ? AND (ts > ? OR (ts = ? AND rowid > ?))
|
|
205
|
+
ORDER BY ts, rowid LIMIT ?`).all(row.instance, row.ts, row.ts, row.rowid, around);
|
|
206
|
+
return { doc: full(row), before: before.map(full), after: after.map(full) };
|
|
207
|
+
}
|
|
208
|
+
close() { try {
|
|
209
|
+
this.db.close();
|
|
210
|
+
}
|
|
211
|
+
catch { /* already */ } }
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* What the index stores of a text: masked, then cut. An open tail is masked first too — the end of what arrived may
|
|
215
|
+
* already be a cut (the history's), and the rules for closed values would otherwise take part of its opener (a lone
|
|
216
|
+
* backslash of \" read as a bare value) — and again after the cut to TEXT_MAX.
|
|
217
|
+
*/
|
|
218
|
+
function indexedText(text) {
|
|
219
|
+
return maskOpenSecretTail(maskSecrets(maskOpenSecretTail(text.slice(0, TEXT_MAX + MASK_MARGIN))).slice(0, TEXT_MAX)).trim();
|
|
220
|
+
}
|
|
221
|
+
function hitOf(r) {
|
|
222
|
+
let ref = {};
|
|
223
|
+
try {
|
|
224
|
+
const v = JSON.parse(r.ref);
|
|
225
|
+
if (v && typeof v === "object" && !Array.isArray(v))
|
|
226
|
+
ref = v;
|
|
227
|
+
}
|
|
228
|
+
catch { /* {} */ }
|
|
229
|
+
return { key: r.key, source: r.source, instance: r.instance, peer: r.peer, sender: r.sender, role: r.role, ts: r.ts, ref };
|
|
230
|
+
}
|
|
231
|
+
function valid(d) {
|
|
232
|
+
return !!d && typeof d.key === "string" && d.key.length > 0 && d.key.length <= 300 && SEARCH_SOURCES.includes(d.source)
|
|
233
|
+
&& typeof d.instance === "string" && d.instance.length > 0 && typeof d.sender === "string" && typeof d.text === "string"
|
|
234
|
+
&& typeof d.ts === "number" && Number.isFinite(d.ts) && (d.peer === undefined || typeof d.peer === "string");
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=search-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-store.js","sourceRoot":"","sources":["../../src/search/search-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #2293: the search index's worker — it alone opens search.db, so no SQLite work of the index runs on the fleet's loop.
|
|
3
|
+
* The fleet posts batches of docs and queries (search-index.ts); this answers queries and says when it is ready and
|
|
4
|
+
* whether the index still needs its backfill. A corrupt file is moved aside (`search.db.corrupt-<stamp>`, with its -wal
|
|
5
|
+
* and -shm) and a fresh one opened — the fleet backfills it; any other failure to open ends the worker (search is then
|
|
6
|
+
* unavailable, the fleet runs on).
|
|
7
|
+
*
|
|
8
|
+
* The backfill of the two sources that live in SQLite is read here too, read-only: the outbox's cross-instance messages
|
|
9
|
+
* (its own retention: 30 days) and the Task Board. A page at a time, yielding between pages, so a query is answered
|
|
10
|
+
* while it runs.
|
|
11
|
+
*/
|
|
12
|
+
import { parentPort, workerData } from "node:worker_threads";
|
|
13
|
+
import { existsSync, renameSync } from "node:fs";
|
|
14
|
+
import Database from "better-sqlite3";
|
|
15
|
+
import { classifySqliteOpenError } from "../sqlite-open-errors.js";
|
|
16
|
+
import { SearchStore } from "./search-store.js";
|
|
17
|
+
import { taskDoc, xmsgDoc, xmsgFromOutbox } from "./search-docs.js";
|
|
18
|
+
const path = String(workerData?.path ?? "");
|
|
19
|
+
const port = parentPort;
|
|
20
|
+
let store = null;
|
|
21
|
+
function moveAside() {
|
|
22
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
23
|
+
for (const suffix of ["", "-wal", "-shm"])
|
|
24
|
+
if (existsSync(path + suffix))
|
|
25
|
+
renameSync(path + suffix, `${path}.corrupt-${stamp}${suffix}`);
|
|
26
|
+
}
|
|
27
|
+
function open() {
|
|
28
|
+
try {
|
|
29
|
+
store = new SearchStore(path);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
if (classifySqliteOpenError(err) !== "corrupt") {
|
|
33
|
+
port.postMessage({ op: "failed", reason: String(err?.message ?? err) });
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
moveAside();
|
|
37
|
+
store = new SearchStore(path);
|
|
38
|
+
}
|
|
39
|
+
port.postMessage({ op: "ready", built: store.built() });
|
|
40
|
+
}
|
|
41
|
+
/** A corrupt file found while working: the same as at open — moved aside, a fresh index, a new backfill. */
|
|
42
|
+
function recover(err) {
|
|
43
|
+
if (classifySqliteOpenError(err) !== "corrupt")
|
|
44
|
+
return false;
|
|
45
|
+
store?.close();
|
|
46
|
+
store = null;
|
|
47
|
+
moveAside();
|
|
48
|
+
open();
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
const BACKFILL_PAGE = 500;
|
|
52
|
+
const MESSAGE_KINDS = ["fleet_inbound", "steer", "broadcast"];
|
|
53
|
+
const pause = () => new Promise(resolve => setImmediate(resolve));
|
|
54
|
+
function readOnly(file) {
|
|
55
|
+
if (!file || !existsSync(file))
|
|
56
|
+
return null;
|
|
57
|
+
try {
|
|
58
|
+
const db = new Database(file, { readonly: true, fileMustExist: true });
|
|
59
|
+
db.pragma("busy_timeout = 1000");
|
|
60
|
+
return db;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** The outbox's cross-instance messages since `cutoff`, then every task: what the fleet recorded before the index. */
|
|
67
|
+
async function backfill(outboxPath, schedulerPath, cutoff) {
|
|
68
|
+
let xmsg = 0, tasks = 0;
|
|
69
|
+
const outbox = readOnly(outboxPath);
|
|
70
|
+
if (outbox)
|
|
71
|
+
try {
|
|
72
|
+
const page = outbox.prepare(`SELECT created_seq AS seq, COALESCE(target_session, target_instance) AS target, created_at AS createdAt, payload_json AS payload, kind
|
|
73
|
+
FROM deliveries WHERE created_seq > ? AND kind IN (${MESSAGE_KINDS.map(() => "?").join(",")}) ORDER BY created_seq LIMIT ?`);
|
|
74
|
+
for (let after = -1;;) {
|
|
75
|
+
const rows = page.all(after, ...MESSAGE_KINDS, BACKFILL_PAGE);
|
|
76
|
+
if (!rows.length || !store)
|
|
77
|
+
break;
|
|
78
|
+
after = rows[rows.length - 1].seq;
|
|
79
|
+
const docs = rows.map(r => xmsgFromOutbox(r.target, r.createdAt, r.payload, r.kind)).map(r => (r ? xmsgDoc(r) : null)).filter(d => d !== null && d.ts >= cutoff);
|
|
80
|
+
xmsg += store.add(docs);
|
|
81
|
+
await pause();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { /* an outbox this can't read: its messages are not found, the rest is */ }
|
|
85
|
+
finally {
|
|
86
|
+
outbox.close();
|
|
87
|
+
}
|
|
88
|
+
const scheduler = readOnly(schedulerPath);
|
|
89
|
+
if (scheduler)
|
|
90
|
+
try {
|
|
91
|
+
const page = scheduler.prepare("SELECT rowid AS rid, id, title, description, result, status, assignee, created_by, created_at, updated_at FROM tasks WHERE rowid > ? ORDER BY rowid LIMIT ?");
|
|
92
|
+
for (let after = -1;;) {
|
|
93
|
+
const rows = page.all(after, BACKFILL_PAGE);
|
|
94
|
+
if (!rows.length || !store)
|
|
95
|
+
break;
|
|
96
|
+
after = rows[rows.length - 1].rid;
|
|
97
|
+
tasks += store.add(rows.map(taskDoc).filter(d => d !== null && d.ts >= cutoff));
|
|
98
|
+
await pause();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch { /* the same for the Task Board */ }
|
|
102
|
+
finally {
|
|
103
|
+
scheduler.close();
|
|
104
|
+
}
|
|
105
|
+
return { xmsg, tasks };
|
|
106
|
+
}
|
|
107
|
+
port.on("message", (m) => {
|
|
108
|
+
if (!store)
|
|
109
|
+
return;
|
|
110
|
+
const reply = (value) => { if (m.id !== undefined)
|
|
111
|
+
port.postMessage({ op: "reply", id: m.id, ok: true, value }); };
|
|
112
|
+
try {
|
|
113
|
+
switch (m.op) {
|
|
114
|
+
// Acked once written: the fleet keeps a batch until then, and sends it again to a worker that replaces this one.
|
|
115
|
+
case "add":
|
|
116
|
+
store.add((m.docs ?? []));
|
|
117
|
+
if (m.batch !== undefined)
|
|
118
|
+
port.postMessage({ op: "added", batch: m.batch });
|
|
119
|
+
break;
|
|
120
|
+
case "markBuilt":
|
|
121
|
+
store.markBuilt(Number(m.now) || Date.now());
|
|
122
|
+
break;
|
|
123
|
+
case "removeInstance":
|
|
124
|
+
if (typeof m.instance === "string") {
|
|
125
|
+
store.removeInstance(m.instance);
|
|
126
|
+
port.postMessage({ op: "removed", instance: m.instance, gen: m.gen });
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
case "query":
|
|
130
|
+
reply(store.search(m.filters));
|
|
131
|
+
break;
|
|
132
|
+
case "context":
|
|
133
|
+
reply(store.context(String(m.key ?? "")));
|
|
134
|
+
break;
|
|
135
|
+
case "prune":
|
|
136
|
+
reply(store.prune(Number(m.cutoff) || 0));
|
|
137
|
+
break;
|
|
138
|
+
case "count":
|
|
139
|
+
reply(store.count());
|
|
140
|
+
break;
|
|
141
|
+
case "backfill":
|
|
142
|
+
void backfill(m.outboxPath, m.schedulerPath, Number(m.cutoff) || 0).then(reply, err => {
|
|
143
|
+
if (m.id !== undefined)
|
|
144
|
+
port.postMessage({ op: "reply", id: m.id, ok: false, error: String(err?.message ?? err) });
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
147
|
+
case "close":
|
|
148
|
+
store.close();
|
|
149
|
+
store = null;
|
|
150
|
+
process.exit(0);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
if (m.id !== undefined)
|
|
155
|
+
port.postMessage({ op: "reply", id: m.id, ok: false, error: String(err?.message ?? err) });
|
|
156
|
+
// A corrupt file: a fresh one, announced as not built (the fleet sends its uncommitted batches again and backfills).
|
|
157
|
+
// Any other failed write is let go (acked): sent again it would fail again.
|
|
158
|
+
if (!recover(err) && m.op === "add" && m.batch !== undefined)
|
|
159
|
+
port.postMessage({ op: "added", batch: m.batch });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
open();
|
|
163
|
+
//# sourceMappingURL=search-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-worker.js","sourceRoot":"","sources":["../../src/search/search-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AAErF,MAAM,IAAI,GAAG,MAAM,CAAE,UAA6C,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;AAChF,MAAM,IAAI,GAAG,UAAW,CAAC;AACzB,IAAI,KAAK,GAAuB,IAAI,CAAC;AAErC,SAAS,SAAS;IAChB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC;QAAE,IAAI,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;YAAE,UAAU,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,IAAI,YAAY,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AAC3I,CAAC;AACD,SAAS,IAAI;IACX,IAAI,CAAC;QAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IACtC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QACxJ,SAAS,EAAE,CAAC;QACZ,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AACD,4GAA4G;AAC5G,SAAS,OAAO,CAAC,GAAY;IAC3B,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7D,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC;IACZ,IAAI,EAAE,CAAC;IACP,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,aAAa,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAC9D,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,SAAS,QAAQ,CAAC,IAAwB;IACxC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC;QAAC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AACrJ,CAAC;AACD,sHAAsH;AACtH,KAAK,UAAU,QAAQ,CAAC,UAA8B,EAAE,aAAiC,EAAE,MAAc;IACvG,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,IAAI,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;2DAC2B,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC/H,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,IAAK,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,aAAa,EAAE,aAAa,CAA6F,CAAC;gBAC1J,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAClC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;gBACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC;gBACjK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAa,CAAC,CAAC;gBACjC,MAAM,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,wEAAwE,CAAC,CAAC;gBAAS,CAAC;YAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAChH,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,IAAI,CAAC;YAClB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,6JAA6J,CAAC,CAAC;YAC9L,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,IAAK,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAwC,CAAC;gBACnF,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAClC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;gBACnC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,MAAM,CAAU,CAAC,CAAC;gBACzF,MAAM,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,iCAAiC,CAAC,CAAC;gBAAS,CAAC;YAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAC5E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAA8M,EAAE,EAAE;IACpO,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,KAAK,GAAG,CAAC,KAAc,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5H,IAAI,CAAC;QACH,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;YACb,iHAAiH;YACjH,KAAK,KAAK;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAU,CAAC,CAAC;gBAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;oBAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAC,MAAM;YACpI,KAAK,WAAW;gBAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAAC,MAAM;YACtE,KAAK,gBAAgB;gBAAE,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM;YAC9K,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC;gBAAC,MAAM;YAC7D,KAAK,SAAS;gBAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAAC,MAAM;YACjE,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAC,MAAM;YAC/D,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAC,MAAM;YAC1C,KAAK,UAAU;gBAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;oBACrG,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;wBAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChI,CAAC,CAAC,CAAC;gBAAC,MAAM;YACV,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;gBAAC,KAAK,GAAG,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9H,qHAAqH;QACrH,4EAA4E;QAC5E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAClH,CAAC;AACH,CAAC,CAAC,CAAC;AACH,IAAI,EAAE,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { join, dirname } from "node:path";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { execFileSync, execSync, spawnSync } from "node:child_process";
|
|
6
|
+
import { ensureUserSystemd } from "./user-systemd.js";
|
|
6
7
|
import ejs from "ejs";
|
|
7
8
|
const { render } = ejs;
|
|
8
9
|
import { homedir, platform } from "node:os";
|
|
@@ -242,6 +243,8 @@ function servicePathForLabel(label) {
|
|
|
242
243
|
}
|
|
243
244
|
/** Inspect the user service without changing it. `null` means manager unavailable. */
|
|
244
245
|
export function inspectService(label = SERVICE_LABEL) {
|
|
246
|
+
if (detectPlatform() === "linux")
|
|
247
|
+
ensureUserSystemd(); // #2264
|
|
245
248
|
const plat = detectPlatform();
|
|
246
249
|
const path = servicePathForLabel(label);
|
|
247
250
|
const manager = plat === "macos" ? "launchd" : "systemd --user";
|
|
@@ -370,6 +373,8 @@ export function launchdPlistPath(label) {
|
|
|
370
373
|
return join(process.env.HOME, "Library/LaunchAgents", `${label}.plist`);
|
|
371
374
|
}
|
|
372
375
|
export function installService(vars) {
|
|
376
|
+
if (detectPlatform() === "linux")
|
|
377
|
+
ensureUserSystemd(undefined, { linger: true }); // #2264: `agend install`
|
|
373
378
|
const plat = detectPlatform();
|
|
374
379
|
if (plat === "macos") {
|
|
375
380
|
const plistPath = launchdPlistPath(vars.label);
|
|
@@ -742,6 +747,8 @@ export function classifySystemdServiceState(result) {
|
|
|
742
747
|
return "stopped";
|
|
743
748
|
}
|
|
744
749
|
export function getSystemdServiceState(label, user = true) {
|
|
750
|
+
if (detectPlatform() === "linux")
|
|
751
|
+
ensureUserSystemd(); // #2264
|
|
745
752
|
const args = [...(user ? ["--user"] : []), "is-active", label];
|
|
746
753
|
const result = spawnSync("systemctl", args, { encoding: "utf8", timeout: 5000 });
|
|
747
754
|
return classifySystemdServiceState(result);
|
|
@@ -763,6 +770,8 @@ export function systemdRestartOutcome(label, user = true, run = execFileSync) {
|
|
|
763
770
|
}
|
|
764
771
|
}
|
|
765
772
|
export function restartSystemdService(label, user = true, run = execFileSync) {
|
|
773
|
+
if (user && run === execFileSync)
|
|
774
|
+
ensureUserSystemd(undefined, { linger: true }); // #2264: a restart
|
|
766
775
|
return systemdRestartOutcome(label, user, run) === "restarted";
|
|
767
776
|
}
|
|
768
777
|
export function getServicePath() {
|
|
@@ -791,6 +800,7 @@ export function stopService() {
|
|
|
791
800
|
execSync(`launchctl bootout gui/${uid}/${SERVICE_LABEL}`, { stdio: "inherit" });
|
|
792
801
|
}
|
|
793
802
|
else {
|
|
803
|
+
ensureUserSystemd(); // #2264: the bus a non-login shell left out (a stop changes no host setting)
|
|
794
804
|
execSync(`systemctl --user stop ${SERVICE_LABEL}`, { stdio: "inherit" });
|
|
795
805
|
}
|
|
796
806
|
return true;
|
|
@@ -812,6 +822,7 @@ export function startService() {
|
|
|
812
822
|
execSync(`launchctl enable ${domain}/${SERVICE_LABEL}`, { stdio: "inherit" });
|
|
813
823
|
}
|
|
814
824
|
else {
|
|
825
|
+
ensureUserSystemd(undefined, { linger: true }); // #2264: without it, root on WSL got "Failed to connect to bus" and no fleet
|
|
815
826
|
try {
|
|
816
827
|
execSync("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
817
828
|
}
|
|
@@ -873,6 +884,7 @@ export function activateService(plistPath, pidPath) {
|
|
|
873
884
|
}
|
|
874
885
|
else {
|
|
875
886
|
const serviceName = plistPath.replace(/.*\//, "").replace(/\.service$/, "");
|
|
887
|
+
ensureUserSystemd(undefined, { linger: true }); // #2264: linger on, so the fleet outlives the login that installed it
|
|
876
888
|
execSync("systemctl --user daemon-reload", { stdio: "inherit" });
|
|
877
889
|
execSync(`systemctl --user enable --now ${serviceName}`, { stdio: "inherit" });
|
|
878
890
|
}
|