Skip to content

feat: delete bots and crews (daemon and protocol) - #54

Merged
httpsphl merged 3 commits into
mainfrom
feat/delete-bots-crews
Sep 30, 2026
Merged

httpsphl merged 3 commits into
mainfrom
feat/delete-bots-crews

Conversation

@httpsphl

Copy link
Copy Markdown
Owner

What

Bots and crews could only be archived, which hides them and keeps everything. This adds deleting them for good: the daemon methods, the protocol and the app's store. The Delete entries in the menus, with the confirmation, come in the next PR, on top of this one.

  • bots.delete {botId} and crews.delete {crewId}, for active and archived items. They answer {botId, crewId} and {crewId}, and every connected app hears bot.deleted / crew.deleted.
  • The bot stops at once. Its process is killed without waiting for the turn, its token stops working, its browser closes and the browser profile is deleted, and permission requests waiting for the owner let go. The supervisor forgets the bot, and a reconcile pass that had read it just before does not start it again.
  • What leaves the database, in one transaction: the bot, its chat, approvals, the messages it received (with deliveries and attachment records), its routines and their runs, its browser sites and the tasks it asked for or was given. A deleted chief leaves the crew without one.
  • What stays with the other bots: messages the deleted bot sent stay in their chats and in the crew timeline, without a sender (fromBotId: null). One that was still waiting in the queue arrives as from a deleted bot, without the "Reply with send_message" line, since there is nobody to answer.
  • Unfinished tasks. They go with the bot, and the other side is told by Botloft if it still runs: whoever asked the deleted bot reads that the task will not be done; whoever was working for it reads that nobody waits for the result.
  • A crew goes with all its bots, archived ones too.
  • Nothing on disk is deleted except the bot's browser profile: the bot's folder (memory, rules, attachments, what it made), shared\ and a chosen work folder stay. The slug stays taken, so a new bot of the same name gets name-2.
  • App: FakeBotloft implements both methods, and the store drops a deleted bot with its routines, tasks, deliveries and browser (the daemon sends no notification for each of those).
  • Spec: new 7.6 (archive and delete), and 5, 9.3, 9.4, 10.2, 11.2, 11.3, 11.4, 12, 14, 20.3 and 21.2. The row in 14 that said archiving a bot deletes its workspace was never true; it now says what happens.

Decisions

Taken with the owner before implementing:

  • Folders stay. A follow-up PR adds an unchecked box in the confirmation, "also move the folder to the Recycle Bin".
  • Archived items can be deleted too. The daemon accepts them from now; a follow-up PR adds an "Archived" list in the app, since archived items are not shown anywhere today.

Mine, open to change:

  • Hard delete, no tombstone. The foreign keys have no ON DELETE, so the store deletes or lets go of each reference in order. No migration.
  • Tasks are removed, not settled. tasks.requester_bot_id and assignee_bot_id cannot be null, and a task with a side that no longer exists can never be completed. The notice tells the bot that is left.
  • Claude Code's own transcript (%USERPROFILE%\.claude\projects\) is not touched: it is not Botloft's. The spec says so.

Tests

  • crates/botloft-store/src/delete/tests.rs: a bot takes what was its own, what it sent stays without a sender, a chain of tasks loses only the deleted link, a crew takes its bots and leaves other crews alone. Each checks PRAGMA foreign_key_check.
  • crates/botloftd/tests/delete.rs, with FakeRuntime: the process is killed, the supervisor forgets the bot and does not start it again, the folder stays, later calls answer -32002; a waiting permission request lets go at once; a deleted chief; archived bots and crews; a crew with running bots, whose tokens stop working.
  • crates/botloftd/tests/delete_messages.rs: the two task notices, and a message that waited arriving from a deleted bot.
  • app/src/store/app.test.ts with FakeBotloft: the store after bots.delete and crews.delete.
  • cargo fmt, clippy -D warnings, cargo test --workspace and pnpm check pass.

Still to see with real Claude Code

  • Delete a bot in the middle of a turn (bots.delete over the RPC, or from the app once the next PR is in): claude.exe and what it started are gone from Task Manager, nothing starts it again, and the bot's folder is as it was.
  • Delete a bot whose browser is open: msedge.exe of that bot ends and %LOCALAPPDATA%\Botloft\browsers\<bot_id> is removed a few seconds later.

Archiving keeps the rows. Deleting removes the bot with its chat, approvals, the messages it received, its routines, browser sites and tasks, in one transaction; what it sent to other bots stays without a sender.
The methods, the bot.deleted and crew.deleted notifications, the fake daemon and the app store, which drops a deleted bot with its routines, tasks and deliveries.
bots.delete and crews.delete work on active and archived items (spec 7.6). The process is killed at once and the supervisor forgets the bot; the database loses the bot and what was its own; folders stay on disk (spec 5). Other bots are told about the unfinished tasks a deleted bot leaves, and a message of its that still waited arrives as from a deleted bot.

The spec row that said archiving deletes the workspace was never true and now says what happens.
@httpsphl
httpsphl merged commit d0d7bcc into main Sep 30, 2026
3 checks passed
httpsphl added a commit that referenced this pull request Sep 30, 2026
docs/spec.md: the browser's profile line keeps both changes: resting (this branch) and deleting a bot, which also closes the browser and deletes its profile (#54).
@httpsphl httpsphl mentioned this pull request Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant