Repository navigation
M5 (2/3): Botloft sets itself up, and an NSIS installer - #11
Merged
Merged
Conversation
…r awake (M5) `botloftd service install|status|restart|uninstall` registers a per-user scheduled task through the Task Scheduler COM API (schtasks output is localized). A logon trigger starts the daemon at logon; a time trigger that repeats every minute with IgnoreNew brings it back after a crash. Tested on Windows 11 25H2: RestartOnFailure does not restart a process that exits with an error, and a logon trigger's repetition only begins at the next logon, so neither can be the watchdog. `service install` copies the running binary to <home>\bin and the task runs that copy, so the app's installer can replace its own files while the daemon runs. A busy exe is renamed aside instead of overwritten. One task per data folder, so a dev BOTLOFT_HOME never replaces the real installation; `--home` overrides BOTLOFT_HOME for every subcommand. The daemon's manifest asks for long paths and no console (consoleAllocationPolicy), embedded as a resource because the linker's manifest tool warns about the new element. Older Windows gets FreeConsole. Fatal start-up errors now reach the log file, since nobody sees the task's stderr. Keep-awake holds a power request while any bot is busy. Unlike SetThreadExecutionState it belongs to a handle, not a thread, which fits Tokio's worker pool. The spec is updated to match.
The app no longer asks the owner to start anything. When nothing runs, it installs the daemon it ships (`daemon_install`, which runs the sidecar's `botloftd service install`); when the running daemon is older than the app, it updates it the same way. Each check installs or updates at most once, so a failure shows instead of looping. `daemon_start` is gone; `daemon_restart` backs a "Restart Botloft in the background" button while a connection does not come up. The owner never has to know that a daemon, a port or a scheduled task exists: the interface says "Botloft" and "in the background", and keeps technical text (errors, paths, ports) folded under "Details". A missing Claude Code links to its official setup page from the welcome screen and the "Bots can't start" banner. botloftd now prints errors on one line (`what failed: why`), which the app shows as is.
`pnpm bundle` builds botloftd for release, copies it where Tauri looks for the sidecar and runs `tauri build` with tauri.bundle.conf.json, which turns on `externalBin` and the per-user NSIS installer. It stays out of tauri.conf.json because tauri-build copies `externalBin` in dev and in clippy too, which would demand the release sidecar on every build and overwrite target\debug\botloftd.exe. The installer never touches the running daemon: the daemon runs from its own copy in the data folder, so the sidecar file is never in use. Its uninstall hook runs `botloftd service uninstall` on a real uninstall and does nothing when an update runs the old uninstaller with /UPDATE; the app updates the daemon when it next opens. Bots and data stay. The app's exe is now Botloft.exe and its manifest adds longPathAware to Tauri's default. The README no longer describes the ConPTY runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second M5 slice. It sits on top of #10 (the first commit here is #10's). Once #10 merges with a merge commit, this diff shrinks to the two app commits.
Setup without questions or jargon
daemon_install, which runs the bundledbotloftd service installfrom M5 (1/3): start at logon as a scheduled task, keep the computer awake #10. When the running daemon is older than the app, it updates it the same way. Each check installs or updates at most once, so a failure shows up instead of looping.daemon_startis removed;daemon_restartbacks a "Restart Botloft in the background" button for when a connection doesn't come up.botloftdnow prints errors on one line (what failed: why), and the app shows that line under Details.Installer
pnpm bundlebuilds the release sidecar (scripts/sidecar.mjs) and runstauri build --config src-tauri/tauri.bundle.conf.json. That file holdsexternalBinand the per-user NSIS config. It stays out oftauri.conf.jsonbecausetauri-buildcopiesexternalBinin dev and during clippy as well: that would require the release sidecar for every build and would overwritetarget\debug\botloftd.exe.%LOCALAPPDATA%\Botloft(Tauri's default), with no admin prompt. That is also the data folder. File names don't collide, and the uninstaller only deletes what it installed, so the data survives an uninstall (spec 5).hooks.nsh: a real uninstall runsbotloftd service uninstall. An update also runs the old uninstaller, but with/UPDATE; the hook skips that case, the daemon keeps running, and the app updates it the next time it opens.Botloft.exe(mainBinaryName), and its manifest addslongPathAware.Tested
pnpm check: 48 tests pass. Clippy and the Rust tests pass.BOTLOFT_HOME):Botloft.exe,botloftd.exeanduninstall.exeare in place, and the Add/Remove Programs entry is registered;bin;/UPDATE: the daemon keeps running with the same PID;Manual test (clean machine)
pnpm bundle, copytarget\release\bundle\nsis\Botloft_0.1.0_x64-setup.exeto a machine that has Claude Code signed in, and run it. The finish page opens Botloft, which should land on the welcome screen without asking anything.Get-ScheduledTask Botloftfinds nothing) and%LOCALAPPDATA%\Botloftkeeps the data.The installer is not code-signed yet, so SmartScreen will warn on first run.