diff --git a/.github/ISSUE_TEMPLATE/antivirus.yml b/.github/ISSUE_TEMPLATE/antivirus.yml new file mode 100644 index 00000000..e355c563 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/antivirus.yml @@ -0,0 +1,38 @@ +name: Antivirus warning +description: Your antivirus or SmartScreen flagged a Botloft download or the installed app. +labels: [bug] +body: + - type: markdown + attributes: + value: | + Botloft's releases are not code-signed yet, so an antivirus may flag them by guesswork + (a "machine-learning" or "heuristic" detection). The + [code signing policy](https://github.com/httpsphl/botloft/blob/main/docs/code-signing-policy.md) + explains why and how each release is built. We report every false positive to the vendor. + - type: input + id: file + attributes: + label: File + description: The name of the file that was flagged. + placeholder: Botloft_0.8.0_x64-setup.exe + validations: + required: true + - type: input + id: antivirus + attributes: + label: Antivirus + placeholder: Microsoft Defender + validations: + required: true + - type: input + id: detection + attributes: + label: Detection name + placeholder: Trojan:Win32/Wacatac.C!ml + validations: + required: true + - type: textarea + id: more + attributes: + label: Anything else + description: When it happened (on download, on install, while running) and a VirusTotal link, if you have one. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..077e50ca --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,55 @@ +name: Bug report +description: Something in Botloft does not work as it should. +labels: [bug] +body: + - type: markdown + attributes: + value: | + Thanks for reporting. Please leave out anything private: bot conversations, file contents, + tokens or names you would not post publicly. + - type: textarea + id: what + attributes: + label: What happened + description: What you saw, and what you expected instead. + validations: + required: true + - type: textarea + id: steps + attributes: + label: Steps to reproduce + placeholder: | + 1. Open a crew with ... + 2. Send ... + 3. ... + validations: + required: true + - type: input + id: version + attributes: + label: Botloft version + description: Settings > About shows it. + placeholder: "0.8.0" + validations: + required: true + - type: dropdown + id: os + attributes: + label: System + options: + - Windows + - Linux + - macOS + validations: + required: true + - type: input + id: claude + attributes: + label: Claude Code version + description: Settings > About shows it too. Most useful when the problem involves bots. + - type: textarea + id: logs + attributes: + label: Logs or screenshots + description: Anything that helps. Check logs for private content before pasting. + render: text diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..fe30329b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Security problem + url: https://github.com/httpsphl/botloft/security/advisories/new + about: Report it privately, not in a public issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..41e5e510 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,22 @@ +name: Idea or feature request +description: Something Botloft could do, or do better. +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: What you want to do + description: The situation and what gets in the way today. A real example helps most. + validations: + required: true + - type: textarea + id: idea + attributes: + label: How it could work + description: Your idea, if you have one. Rough is fine. + - type: checkboxes + id: help + attributes: + label: Building it + options: + - label: I would like to work on this myself. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..32de21bd --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,15 @@ +## What and why + + + +## How it was tested + + + +## Checklist + +- [ ] `cargo fmt`, `clippy -D warnings` and `cargo test` pass +- [ ] `pnpm check` passes (if the app changed) +- [ ] New behavior has a test +- [ ] New interface text is in English, Portuguese and Spanish +- [ ] `docs/spec.md` still matches the code diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..80deac34 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,101 @@ +# Contributing to Botloft + +Thanks for taking a look. Botloft is young (version 0.x) and every kind of help counts: trying it and +reporting what broke, ideas, docs, translations and code. + +## Ways to help + +- **Try it and tell us.** A bug report with the steps to reproduce it is one of the most useful + things you can send. Use the [bug report form](https://github.com/httpsphl/botloft/issues/new/choose). +- **Antivirus false positives.** Releases are not code-signed yet (see the + [code signing policy](docs/code-signing-policy.md)), so an antivirus may flag them by guesswork. + If yours does, open an issue with the file name, the detection name and the antivirus; we report + each one to the vendor. +- **Pick an issue.** Issues labeled + [`good first issue`](https://github.com/httpsphl/botloft/labels/good%20first%20issue) are small and + self-contained; [`help wanted`](https://github.com/httpsphl/botloft/labels/help%20wanted) ones are + bigger. Comment on the issue before you start so two people do not do the same work. +- **Translations.** The app speaks English, Brazilian Portuguese and Spanish. Fixes to wording are + welcome in any of them. +- **Bigger changes.** For a new feature or a change in how something works, open an issue first and + describe it. It saves you from writing code that does not fit the plan. + +## Getting set up + +The [Development section of the README](README.md#status) lists what to install and the commands to +build and test. The short version: + +```powershell +cargo test --workspace +cd app +pnpm install +pnpm dev # the UI alone in a browser, with a fake daemon and sample crews +``` + +`pnpm dev` needs neither Rust nor Claude Code, so it is the quickest way to work on the interface. +Running real bots needs Claude Code installed and signed in. + +During development, set `BOTLOFT_HOME` to an absolute path (for example `$PWD\.dev\home`) for both +the daemon and the app, so they never touch a real Botloft installation. + +## How the project is organized + +``` +crates/botloft-core domain types, IDs, message envelope, protocol types (exported to TypeScript) +crates/botloft-store SQLite storage, migrations in migrations/NNNN_name.sql +crates/botloftd the daemon: RPC, supervisor, bot runtime, chat, message delivery, MCP tools +app/ Tauri v2 + React 19 + TypeScript (strict) + Tailwind v4 + Zustand +docs/ specification and architecture decision records +``` + +[`docs/spec.md`](docs/spec.md) is the source of truth for architecture, protocol, data and states. +It is written in Portuguese; a browser translation reads fine, and questions about it are welcome in +an issue. If your change makes the spec wrong, update the spec in the same pull request. + +## Rules for code + +- **Write it yourself.** Botloft is its own implementation. Do not copy or adapt code, tests, texts + or schemas from other agent orchestration projects. The spec, the official Claude Code + documentation and the documentation of the libraries we use are fine sources. +- **English** for code, identifiers, comments and commit messages. +- **Small files.** Keep files under about 300 lines; split by responsibility past that. +- **Errors:** `thiserror` in the library crates, `anyhow` only in the binary. +- **Platform code** (Win32, systemd, launchd) lives in `crates/botloftd/src/platform/`. The rest of + the daemon does not call the OS directly. +- **The UI talks only to `BotloftApi`** (`app/src/lib/api.ts`). Component tests use `FakeBotloft`. +- **No interface text inside components.** Every string goes in + `app/src/i18n/{en,pt-BR,es}/.ts`, in all three languages, and is read with `useT()`. The + TypeScript check flags a missing one. Use plain words: the app never says "daemon" or other jargon + to the user. +- **Never edit `app/src/lib/protocol.gen.ts` by hand.** It is generated from the Rust types with + `cargo test -p botloft-core export_bindings`. +- **Privacy.** Never log tokens, message bodies, attachments or chat items at `info` level or + above: bots may handle personal data. No telemetry. + +## Before you open a pull request + +1. `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- -D warnings` and + `cargo test --workspace` pass. +2. If you changed the app: `pnpm check` passes (typecheck, Biome and Vitest). +3. New behavior has a test. The supervisor, message delivery and chat are tested with + `FakeRuntime`; components with `FakeBotloft`. +4. The spec still describes what the code does. +5. If the change depends on how the real Claude Code behaves, say in the pull request how you tested + it by hand. + +Keep pull requests small, one change each, with a title in +[Conventional Commits](https://www.conventionalcommits.org) form, such as +`fix(chat): keep the draft when a bot restarts`. CI runs on Windows, Ubuntu and macOS and must pass +before merging. + +Using an AI assistant to write your contribution is fine. You are still the one who answers for it: +read every line, run the checks and make sure it follows the rules above. + +## License + +Botloft is licensed under the [Apache License 2.0](LICENSE). By sending a contribution, you agree +that it is licensed under the same terms (section 5 of the license). + +## Security + +Please do not open a public issue for a security problem. See [SECURITY.md](SECURITY.md). diff --git a/README.md b/README.md index ac1a7680..50f0ab0b 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ How it works  ·  FAQ +  ·  + Contributing

@@ -193,9 +195,9 @@ and is not affiliated with or endorsed by Anthropic. ## Status Botloft is young (version 0.x) and moves fast. The daemon, the chat, crews with a Chief, messages -and tasks between bots, routines, the live browser, screens, the installer and updates are in place. -Planned next: a question box where bots ask you things, "always allow" for requests, search, and a -code-signed installer. `main` can be ahead of the latest release. +and tasks between bots, routines, the live browser, screens, "always allow" for requests, the +installer and updates are in place. Planned next: a question box where bots ask you things, search, +and a code-signed installer. `main` can be ahead of the latest release.
Development @@ -246,6 +248,13 @@ docs/ specification and ADRs ```
+## Contributing + +Contributions are welcome: bug reports, ideas, translations and code. Start with +[CONTRIBUTING.md](CONTRIBUTING.md); issues labeled +[`good first issue`](https://github.com/httpsphl/botloft/labels/good%20first%20issue) are a good +first step. Security problems go through [SECURITY.md](SECURITY.md), not public issues. + ## License Botloft is licensed under the [Apache License 2.0](LICENSE). See [NOTICE](NOTICE) for the copyright diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..1e00f28a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,32 @@ +# Security policy + +## Reporting a problem + +Please report security problems privately, through GitHub: +[Report a vulnerability](https://github.com/httpsphl/botloft/security/advisories/new). Do not open a +public issue. + +Say what you found, how to reproduce it and which version you used. You will get an answer within a +week. Once a fix is out, the advisory is published with credit to you, unless you prefer otherwise. + +## Supported versions + +Only the [latest release](https://github.com/httpsphl/botloft/releases/latest) gets security fixes. +The app updates itself, so staying on it is one click. + +## Scope + +Botloft runs Claude Code bots on your computer, with your account. Some things are by design and not +vulnerabilities: + +- Bots run as your user, without a sandbox. Keeping them apart is cooperative: a bot that may run + any command (or one set to skip permission prompts) can read what your user can read, including + other bots' folders and Botloft's own data. The app warns about this before you turn that on. +- The background service listens on `127.0.0.1` only and asks every client for a token, which only + your user can read. Other programs running as your user are trusted as much as you are. + +A way around what a bot was allowed to do, a page or a message that gets a bot past a permission +prompt, or a program reaching the service without the token is in scope and very welcome. + +Antivirus detections of the releases are not security reports: see the +[code signing policy](docs/code-signing-policy.md) and open a normal issue. diff --git a/docs/code-signing-policy.md b/docs/code-signing-policy.md index 69dbd05a..9278b81d 100644 --- a/docs/code-signing-policy.md +++ b/docs/code-signing-policy.md @@ -83,8 +83,9 @@ On Linux and macOS (preview since 0.8.0): `~/Library/Application Support/Botloft`. A launch agent, `~/Library/LaunchAgents/io.github.httpsphl.botloft.daemon.plist`, keeps the bots running; when Botloft opens its window at sign-in, it adds `io.github.httpsphl.botloft.app.plist` next to it. -- Bots keep their work in `~/Botloft`, or in the folder you pick for a crew. Keeping the computer - awake while bots work is Windows-only for now. +- Bots keep their work in `~/Botloft`, or in the folder you pick for a crew. +- While a bot is working, a helper keeps the computer from sleeping when idle: `caffeinate` on + macOS, `systemd-inhibit` on Linux. Settings > General turns this off. ## Uninstalling