Important
Note for contributors: When branching out, create a new branch from the dev branch.
You are seeing this probably because you want to contribute to our project, and we welcome you! To ensure contributor feels welcome, we have this guide to help you get started and ensure your contributions can be efficiently integrated into the project.
Here are all the things you to contribute to the community.
- 📝 Submitting bug reports or feature requests
- 💡 Improving documentation
- 🔍 Perform tests and fixing bugs
- 🛠️ Contributing code
- 🌐 Helping other users
- Open an issue for bug reports, feature requests, or discussions
- Submit pull requests to contribute code or documentation
- Join ongoing discussions in existing issues and PRs
- Join our Discord community for real-time discussions
- Join our voice channel for direct communication.
- Participate in community events (if we have any).
- Get help from other community members
- Email: thamyikfoong@craftos.net
- For business inquiries or sensitive matters, please reach out directory via email
- For general questions, prefer public channels like GitHub issues or Discord
For faster responses, consider using our Discord channel where the whole community can help!
- Fork the CraftBot repository
- Clone your fork:
git clone https://github.com/<your-github-username>/CraftBot.git
cd CraftBotKeep it simple. The point is shared rhythm, not bureaucracy.
- Base off
dev, nevermainorstaging. - Name:
type/short-description— kebab-case.- Types:
feat,fix,chore,refactor,docs,hotfix - Examples:
feat/discord-role-sync,fix/webhook-retry-loop
- Types:
- One branch = one focused change. If it grows past ~400 lines or two days of work, split it.
- Delete the branch after merge.
Flow: dev → staging → main. Never push directly to staging or main.
Create a new branch for your work:
git checkout -b feat/your-feature-nameTo help fix a bug:
git checkout -b fix/bug-nameFormat:
<type> <issue number if exists eg: #245>: <short summary in imperative mood>
<optional body — why, not what>
- Types:
feat,fix,chore,refactor,docs,test,style - Summary ≤ 72 chars, no period, imperative ("add" not "added").
- Body explains why the change was needed if it's not obvious. The diff shows what.
- Commit often, but each commit should pass lint/build on its own.
Good:
fix: prevent duplicate role assignment on rejoinfeat: add /ban-history slash command
Bad:
update stuffWIPfixed the thing John mentioned
Before committing, run lint — see section 5. Then:
git add .
git commit -s -m "feat: your descriptive message"
git push origin your-branch-nameCraftBot uses ruff for both formatting and linting. The same checks run in CI on the staging branch (see .github/workflows/staging-lint.yml).
Install if you don't have it:
pip install ruffRun before every commit:
ruff format . # auto-format your code
ruff check . # lintAuto-fix what ruff can fix:
ruff check . --fixCI smoke test (catches broken imports and syntax errors that ruff misses):
python -m compileall -q app agent_core agents decorators skills| Code | What it means | Fix |
|---|---|---|
| F401 | Unused import | Delete it. If it's an __init__.py re-export, add to __all__. |
| F841 | Unused local variable | Delete it. If it's the return of a side-effecting call, drop the LHS (foo() instead of x = foo()). |
| F821 | Undefined name | Real bug. Missing import or typo. |
| F402 | Import shadowed by loop variable | Real bug. Rename the loop variable. |
| E402 | Import not at top of file | Move it up. If ordering is load-bearing (sys.path setup, logging suppression, asyncio shims), add the file to [lint.per-file-ignores] in .ruff.toml. |
| E712 | == True / == False comparison |
Use if x: / if not x:. For SQLAlchemy filters use .is_(True). |
| E722 | Bare except: |
Replace with except Exception: (still catches everything you want, lets KeyboardInterrupt/SystemExit propagate). |
| E741 | Ambiguous variable name (l, I, O) |
Rename — e.g. l → line, label, loop, depending on context. |
The repo ships a .ruff.toml that:
- Excludes
app/data/living_ui_template/— that directory contains Jinja templates with{{placeholders}}, not valid Python. - Ignores E402 per-file for a small set of files (logging setup, asyncio shims, registry init) where import ordering is deliberate.
Do not add new entries casually. If you hit E402 in a new file, prefer moving the import; only add the file to the ignore list if the ordering is genuinely load-bearing, and explain why in your commit.
Title: same format as a commit (feat: …, fix: …). Keep under ~70 chars.
Description template:
## What
1-3 bullets on what changed.
## Why
The problem this solves or the goal. Link the issue: Closes #123
## How to test
Steps to verify locally. Include any env vars, seed data, or commands.
## Screenshots / Logs
If UI or behavior changed.Rules:
- Open as Draft until it's ready for review.
- Keep PRs small — under ~400 lines of diff where possible. Big PRs get stale and miss bugs.
- Self-review your own diff before requesting review. Catch the obvious stuff first.
- At least 1 approval before merge. No self-merging on shared branches.
- Squash-merge into
dev(keeps history clean). Merge-commit intostaging/main. - Resolve all conversations before merging.
- If CI is red, fix it — don't merge around it.
Open a PR:
- Go to the CraftBot repository
- Click "Compare & Pull Request" and open a PR against
dev - Fill in the PR template with details about your changes
Bug template:
**What happened:**
**What I expected:**
**Steps to reproduce:**
1.
2.
**Environment:** (browser, OS, server, version/commit)
**Logs / screenshots:**Feature template:
**Problem:** What user pain are we solving?
**Proposal:** What should it do?
**Out of scope:** What we're *not* doing.
**Acceptance:** How we know it's done.Labels (use at least one):
bug,feature,chore,docs- Priority:
p0(drop everything),p1(this sprint),p2(soon),p3(whenever) blocked,needs-info,good-first-issue
Rules:
- Search before opening — avoid duplicates.
- One problem per issue. Split if it's two things.
- Assign yourself when you start working on it.
- Close with the PR (use
Closes #123in the PR body).
- Be respectful and inclusive
- Help others learn and grow
- Provide constructive feedback
- Ask questions when unsure
- Enjoy building agents
- Open an issue
- Join our Discord community
Thank you for contributing to CraftBot! 🌟