Repository navigation
M4 (1/3): app shell, onboarding, crews and bots - #5
Merged
Merged
Conversation
The app's forms need the daemon's length limits and color palette; the generated file now carries them so the UI never restates them.
Commands for what the page cannot do (spec 15.2): daemon_status checks /health on the port from <home>\config.toml, daemon_start launches the botloftd.exe next to the app detached so it outlives the window, read_owner_token reads the owner token, and open_path opens folders only. The window has no decorations (the app draws its own title bar), and the CSP allows ws://127.0.0.1 on any port so a dev daemon with its own port is reachable.
rpc.ts speaks spec 11 over WebSocket: session.hello first, requests queued until it is accepted, answers matched by id, typed RpcError codes, and reconnection with backoff (0.5 s doubling to 5 s). Requests already sent when the socket drops fail instead of being replayed, since they may have run. A refused hello (token or protocol) stops for good. BotloftApi is the contract components use; client.ts implements it over rpc.ts and FakeBotloft in memory, typed from the generated RpcMethods so every method is covered. Host is the same idea for the Tauri commands and the window.
- Onboarding: finds the daemon, offers to start it, reads the owner token and connects; a taken port, another protocol version or a refused hello each get their own message. The first run lists what is ready (daemon, Claude Code) and explains the one-time folder trust prompt per bot. - Store: crews, bots and system.status load on every (re)connection, then follow crew.changed, bot.changed and bot.state; archived records leave. - Screens: crews and their bots in the sidebar, a crew overview with bot cards, and a bot view with pause, restart (fresh or not), edit, open folder and archive. State reads as color, icon and label; paused bots read as paused. Daemon validation errors stay in the form. - Own title bar with Windows controls, light and dark themes following Windows, IBM Plex type, bot avatars drawn from the mascot. - `pnpm dev` in a plain browser runs the UI against FakeBotloft, for UI work without Tauri or the daemon. The preview is not in release builds.
The docs say a parent folder's trust does not cover a project's permissions.allow rules, and the generated settings allow mcp__botloft, so every new bot asks once; trusting the workspaces root would not help. The app explains the prompt instead, and Botloft leaves ~/.claude.json alone. Spec 15 gains daemon_start (M4, replaced by the service in M5) and how the app finds the daemon's port. The dev config now lives inside the dev BOTLOFT_HOME so the daemon and the app share it.
This was referenced Sep 28, 2026
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.
First of three slices of M4 (spec 17): the app connects to the daemon and manages crews and bots. The terminal (xterm.js) and the message timeline come next, in their own PRs.
What changes
daemon_statuschecks/healthon the port read from<BOTLOFT_HOME>\config.toml, the same folder the daemon uses. A dev daemon is found without extra setup.daemon_startstarts thebotloftd.exenext to the app. It runs detached, without a console and outside the app's job, so it outlives the window. M5 replaces this with the scheduled task.read_owner_tokenreads the owner token.open_pathopens folders only (Explorer would run a file).lib/rpc.ts,client.ts):session.hellofirst.RpcErrorcodes.BotloftApi: the contract components use. There are two implementations: the real client, andFakeBotloft, an in-memory daemon typed from the generatedRpcMethods.Hostdoes the same for the Tauri commands and the window.system.statusload on every (re)connection, then follow the notifications.system.statushas no notification, so it is re-read every 15 s.runtimeError).protocol.gen.ts, so the forms never restate them.pnpm devpreview: opened in a plain browser, it runs the UI againstFakeBotloft, for UI work without Tauri or the daemon. Release builds do not include it.Spec changes
permissions.allowrules. The generated settings allowmcp__botloft, so every new bot shows the trust prompt once, and "trust the workspaces root in onboarding" would not help.~/.claude.json, because Claude Code owns and rewrites that file.Host,daemon_start, and how the app finds the port.config.tomlnow lives inside the devBOTLOFT_HOME, so the daemon and the app share it.Tests
rpc.test.ts(fake socket):close.store/app.test.ts:bot.state, and archiving a bot or a whole crew;link.test.ts: running, stopped then started, did not come up, protocol mismatch, missing token, taken port, refused hello.App.test.tsx(FakeHost + FakeBotloft):daemon.rs): port from the config, a closed port, and a port held by something else.pnpm check,pnpm build, clippy and fmt pass. Each commit typechecks and passes its tests on its own.Checked against the real daemon
client.tsran against a fresh dev daemon:crews.create/list/archive, and a validation error asRpcError−32004;crew.changednotifications arrived;failedwith no retries.http://localhost:1420, the dev webview) passed the Origin check and got the hello answer.Manual test (needs the Tauri window)
target\debug\botloftd.exeand shows the first-run checklist.