Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 0 additions & 2 deletions .github/workflows/staging-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip

- name: Install ruff
run: pip install ruff
Expand All @@ -36,7 +35,6 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip

- name: Byte-compile source tree
run: python -m compileall -q app agent_core agents decorators skills
17 changes: 17 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extend-exclude = [
"app/data/living_ui_template",
]

# E402 (module-level imports not at top) is triggered in files that deliberately
# run setup code before imports — logging suppression, sys.path manipulation,
# asyncio compatibility shims, or state-registry initialization that other
# modules depend on at import time. These orderings are load-bearing.
[lint.per-file-ignores]
"agent_core/core/impl/context/engine.py" = ["E402"]
"agent_core/core/prompts/__init__.py" = ["E402"]
"agents/dog_agent/data/action/dog_behaviour.py" = ["E402"]
"app/action/action_framework/run_actions_tests.py" = ["E402"]
"app/config.py" = ["E402"]
"app/llm_interface.py" = ["E402"]
"app/main.py" = ["E402"]
"craftos_integrations/__init__.py" = ["E402"]
175 changes: 154 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,54 +52,187 @@ git clone https://github.com/<your-github-username>/CraftBot.git
cd CraftBot
```

### Create a Branch
---

# 📋 Workflow SOPs

Keep it simple. The point is shared rhythm, not bureaucracy.

## 3. 🌿 Branches

- Base off `dev`, never `main` or `staging`.
- Name: `type/short-description` — kebab-case.
- Types: `feat`, `fix`, `chore`, `refactor`, `docs`, `hotfix`
- Examples: `feat/discord-role-sync`, `fix/webhook-retry-loop`
- 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:
```shell
git checkout -b feature/your-feature-name
git checkout -b feat/your-feature-name
```

To help fix a bug:
```shell
git checkout -b bug/bug-name
git checkout -b fix/bug-name
```

Always branch from the `dev` branch.
## 4. ✅ Commits

## 3. 🎯 Making Changes
**Format:**
```
<type> <issue number if exists eg: #245>: <short summary in imperative mood>

1. **Code Style**: Follow the project's coding standards
2. **Documentation**: Update relevant documentation
3. **Tests**: Add tests for new features
4. **Commits**: Write clear and detail commit messages
<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 rejoin`
- `feat: add /ban-history slash command`

## 4. 📤 Submitting Changes
**Bad:**
- `update stuff`
- `WIP`
- `fixed the thing John mentioned`

1. Install ruff on your system
2. Run ```ruff format .``` and ``` ruff check ``` and fix the issues
3. Push your changes:
Before committing, run lint — see [section 5](#5--linting). Then:
```shell
git add .
git commit -s -m "Description of your changes"
git commit -s -m "feat: your descriptive message"
git push origin your-branch-name
```

2. Create a Pull Request:
- Go to the [**CraftBot** repository](https://github.com/CraftOS-dev/CraftBot)
- Click "Compare & Pull Request" and open a PR against dev branch
- Fill in the PR template with details about your changes
## 5. 🧹 Linting

CraftBot uses [**ruff**](https://docs.astral.sh/ruff/) for both formatting and linting. The same checks run in CI on the `staging` branch (see [`.github/workflows/staging-lint.yml`](.github/workflows/staging-lint.yml)).

Install if you don't have it:
```shell
pip install ruff
```

**Run before every commit:**
```shell
ruff format . # auto-format your code
ruff check . # lint
```

**Auto-fix what ruff can fix:**
```shell
ruff check . --fix
```

**CI smoke test** (catches broken imports and syntax errors that ruff misses):
```shell
python -m compileall -q app agent_core agents decorators skills
```

### Common errors and how to fix them

| 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`](.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. |

### About `.ruff.toml`

The repo ships a [`.ruff.toml`](.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.

## 6. 🔀 Pull Requests

**Title:** same format as a commit (`feat: …`, `fix: …`). Keep under ~70 chars.

**Description template:**
```markdown
## 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 into `staging`/`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](https://github.com/CraftOS-dev/CraftBot)
- Click "Compare & Pull Request" and open a PR against `dev`
- Fill in the PR template with details about your changes

## 7. 🐛 Issues

**Bug template:**
```markdown
**What happened:**
**What I expected:**
**Steps to reproduce:**
1.
2.
**Environment:** (browser, OS, server, version/commit)
**Logs / screenshots:**
```

**Feature template:**
```markdown
**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 #123` in the PR body).

---

## 5. 🤝 Community Guidelines
## 8. 🤝 Community Guidelines

- Be respectful and inclusive
- Help others learn and grow
- Provide constructive feedback
- Ask questions when unsure
- Enjoy building agents

## 6. 📫 To Get Help
## 9. 📫 To Get Help

- Open an [issue](https://github.com/CraftOS-dev/CraftBot)
- Join our Discord community

Thank you for contributing to **CraftBot**! 🌟
Thank you for contributing to **CraftBot**! 🌟
2 changes: 1 addition & 1 deletion README.cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ CraftBot 嵌入在每个 Living UI 之中,并且**对其状态保持感知**:它

**备选方案:** 改用无需 Node.js 的 TUI 模式:
```bash
python run.py --tui
python run.py --cli
```

### 安装时依赖失败
Expand Down
2 changes: 1 addition & 1 deletion README.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Wenn du beim Ausführen von `python run.py` **„npm not found in PATH"** siehst

**Alternative:** Nutze den TUI-Modus, für den kein Node.js nötig ist:
```bash
python run.py --tui
python run.py --cli
```

### Installation scheitert an Abhängigkeiten
Expand Down
2 changes: 1 addition & 1 deletion README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Si al ejecutar `python run.py` ves **"npm not found in PATH"**:

**Alternativa:** Usa el modo TUI, que no requiere Node.js:
```bash
python run.py --tui
python run.py --cli
```

### La instalación falla por dependencias
Expand Down
2 changes: 1 addition & 1 deletion README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Si vous voyez **« npm not found in PATH »** en lançant `python run.py` :

**Alternative :** utilisez le mode TUI, qui ne nécessite pas Node.js :
```bash
python run.py --tui
python run.py --cli
```

### L'installation échoue à cause des dépendances
Expand Down
2 changes: 1 addition & 1 deletion README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ CraftBotはすべてのLiving UIに組み込まれており、**状態を常に

**代替手段:** Node.jsが不要なTUIモードを使う:
```bash
python run.py --tui
python run.py --cli
```

### 依存関係のせいでインストールに失敗する
Expand Down
2 changes: 1 addition & 1 deletion README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ CraftBot은 모든 Living UI에 내장되어 있으며 그 **상태를 항상

**대안:** Node.js가 필요 없는 TUI 모드를 사용하세요:
```bash
python run.py --tui
python run.py --cli
```

### 의존성 때문에 설치가 실패할 때
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ If you see **"npm not found in PATH"** when running `python run.py`:
2. Install and restart your terminal
3. Run `python run.py` again

**Alternative:** Use TUI mode instead (no Node.js needed):
**Alternative:** Use CLI mode instead (no Node.js needed):
```bash
python run.py --tui
python run.py --cli
```

### Installation Fails with Dependencies
Expand Down
2 changes: 1 addition & 1 deletion README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Se ao rodar `python run.py` você vir **"npm not found in PATH"**:

**Alternativa:** Use o modo TUI, que não precisa de Node.js:
```bash
python run.py --tui
python run.py --cli
```

### A instalação falha por dependências
Expand Down
2 changes: 1 addition & 1 deletion README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ CraftBot 嵌入在每一個 Living UI 中,並且**對其狀態保持感知**:它

**替代方案:** 改用不需要 Node.js 的 TUI 模式:
```bash
python run.py --tui
python run.py --cli
```

### 安裝時相依套件失敗
Expand Down
7 changes: 7 additions & 0 deletions agent_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
UsageEventData,
ReportUsageHook,
)

# Implementations
from agent_core.core.impl.action import (
ActionExecutor,
Expand All @@ -166,6 +167,7 @@
EventStream,
EventStreamManager,
)

# Prompts
from agent_core.core.prompts import (
# Registry
Expand Down Expand Up @@ -200,6 +202,7 @@
SKILL_SELECTION_PROMPT,
ACTION_SET_SELECTION_PROMPT,
)

# MCP
from agent_core.core.impl.mcp import (
MCPServerConfig,
Expand All @@ -211,6 +214,7 @@
MCPActionAdapter,
set_client_info as set_mcp_client_info,
)

# Skill
from agent_core.core.impl.skill import (
Skill,
Expand All @@ -220,6 +224,7 @@
SkillManager,
skill_manager,
)

# Onboarding
from agent_core.core.impl.onboarding import (
OnboardingState,
Expand All @@ -230,11 +235,13 @@
load_state as load_onboarding_state,
save_state as save_onboarding_state,
)

# Settings
from agent_core.core.impl.settings import (
SettingsManager,
settings_manager,
)

# Config Watcher
from agent_core.core.impl.config import (
ConfigWatcher,
Expand Down
4 changes: 3 additions & 1 deletion agent_core/core/action/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class Action:
parallelizable: Whether this action can run in parallel with others
"""

DEFAULT_TIMEOUT: int = 6000 # 100 minutes max timeout (GUI mode might need more time)
DEFAULT_TIMEOUT: int = (
6000 # 100 minutes max timeout (GUI mode might need more time)
)

def __init__(
self,
Expand Down
Loading
Loading