Skip to content

Commit be98512

Browse files
committed
Clawbits - agent-native team chat, initial OSS commit
0 parents  commit be98512

1,269 files changed

Lines changed: 318822 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
.git
2+
.github
3+
.claude
4+
.idea
5+
.vscode
6+
.venv
7+
venv
8+
env
9+
__pycache__
10+
*.py[cod]
11+
.pytest_cache
12+
.ruff_cache
13+
.mypy_cache
14+
.coverage
15+
htmlcov
16+
17+
# SQLite remnants — will be deleted post-migration
18+
*.db
19+
*.sqlite
20+
*.sqlite3
21+
22+
# Frontend artifacts — the Docker frontend stage rebuilds these
23+
frontend/node_modules
24+
frontend/dist
25+
26+
# Node elsewhere
27+
node_modules
28+
29+
# Local env — keep .env.keys and any plaintext .env out of the image,
30+
# but ship the encrypted per-env files so dotenvx can decrypt at boot.
31+
.env
32+
.env.keys
33+
.env.*
34+
# Dockerfile COPYs `.env.*`, so at least one match must always exist or the
35+
# build errors with "no source files". .env.example guarantees that even when
36+
# nobody has run scripts/sync_env.sh — it holds no secrets, only defaults.
37+
!.env.example
38+
!.env.development
39+
!.env.staging
40+
!.env.production
41+
42+
# Docs and local-only files
43+
docs
44+
*.md
45+
!README.md
46+
tests
47+
48+
# Shell scripts (container uses CMD directly)
49+
scripts/
50+
51+
# OS
52+
.DS_Store
53+
54+
# `COPY clawbits /app/clawbits` ships every subpackage, so exclude the training
55+
# artifacts by NAME rather than excluding clawbits/lobstertalk wholesale.
56+
# clawbits/lobstertalk/attention/ is the LIVE attention gate (moved there from
57+
# clawbits/mutualist/) and human_mm_endpoints.py imports it at module level —
58+
# excluding the directory would crash the app on boot, not merely bloat it.
59+
# The corpus alone is 97% of the weight.
60+
clawbits/lobstertalk/synthetic_corpus.json
61+
clawbits/lobstertalk/tslib
62+
clawbits/**/__pycache__

.editorconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_style = space
7+
trim_trailing_whitespace = true
8+
insert_final_newline = true
9+
10+
[*.{py}]
11+
indent_style = space
12+
indent_size = 4
13+
14+
15+
[*.json]
16+
indent_style = space
17+
indent_size = 2
18+
19+
[*.yaml]
20+
indent_style = space
21+
indent_size = 2
22+
quote_type = single

.env.example

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Clawbits environment reference.
2+
#
3+
# Copy to `.env` and edit. Every value below is either OPTIONAL or has a working
4+
# default — the app boots with none of them set except the two dev flags in the
5+
# first block, which is the path the README quickstart documents.
6+
#
7+
# Deployments supply these through their own secret store; see docs/SECRETS.md.
8+
#
9+
# ─────────────────────────────────────────────────────────────────────────────
10+
# 1. LOCAL DEV — the whole file you need to start
11+
# ─────────────────────────────────────────────────────────────────────────────
12+
13+
# One of: development | dev | local | test | staging | production.
14+
# The dev-auth panel refuses to load unless this is in the dev set.
15+
CLAWBITS_ENV=development
16+
17+
# Exposes the dev sign-in panel at /login. Sign in with any email; it creates
18+
# the user and their personal org (that org_id is what agent signup needs).
19+
CLAWBITS_DEV_AUTH=1
20+
21+
# Relaxes `Secure` on session cookies so plain http works locally.
22+
CLAWBITS_INSECURE_COOKIES=1
23+
24+
# Skips Cloudflare R2 bucket provisioning at boot. Without this the app tries
25+
# to reach Cloudflare and logs failures on every start.
26+
CLAWBITS_SKIP_R2_PROVISION=1
27+
28+
# ─────────────────────────────────────────────────────────────────────────────
29+
# 2. HAS A DEFAULT — set only to override
30+
# ─────────────────────────────────────────────────────────────────────────────
31+
32+
# Postgres. Default matches `docker compose up -d db`, so leave it unset
33+
# locally. Alembic reads the same variable.
34+
# CLAWBITS_DATABASE_URL=postgresql+psycopg://clawbits:clawbits@localhost:5432/clawbits
35+
36+
# Used only by the test suite; defaults to the `clawbits_test` database.
37+
# CLAWBITS_TEST_DATABASE_URL=postgresql+psycopg://clawbits:clawbits@localhost:5432/clawbits_test
38+
39+
# Canonical user-facing origin: OAuth callbacks and post-login redirects.
40+
CLAWBITS_BASE_URL=http://localhost:5173
41+
CLAWBITS_FRONTEND_URL=http://localhost:5173
42+
43+
# uvicorn worker count in the container image.
44+
# CLAWBITS_WEB_CONCURRENCY=4
45+
46+
# Avatar generation. Defaults to the public DiceBear API; point it at a local
47+
# instance (`http://dicebear:3000/10.x`) to avoid the third-party call.
48+
# DICEBEAR_BASE=https://api.dicebear.com/10.x
49+
50+
# Attention gate tuning (clawbits/mutualist). Both have code defaults.
51+
# CLAWBITS_ATTENTION_THRESHOLD=
52+
# CLAWBITS_ATTENTION_COOLDOWN_SECONDS=30
53+
54+
# Embedding model cache. The container image pre-bakes bge-small into this path
55+
# so workers don't each cold-download it. Consumed by the `fastembed` library.
56+
# FASTEMBED_CACHE_PATH=/app/.cache/fastembed
57+
58+
# ─────────────────────────────────────────────────────────────────────────────
59+
# 3. FEATURE-GATED — unset means the feature is off, cleanly
60+
# ─────────────────────────────────────────────────────────────────────────────
61+
62+
# ── Object storage (Cloudflare R2) ───────────────────────────────────────────
63+
# Unset: attachment uploads return 503 and avatars fall back to letter chips.
64+
# Everything else works. CLOUDFLARE_API_TOKEN is the REST API token;
65+
# R2_ACCESS_KEY_* are S3-compatible keys for presigned browser uploads
66+
# (Cloudflare dashboard → R2 → Manage R2 API Tokens → S3 Compatibility).
67+
CLOUDFLARE_ACCOUNT_ID=
68+
CLOUDFLARE_API_TOKEN=
69+
CLOUDFLARE_BUCKET=
70+
R2_ACCESS_KEY_ID=
71+
R2_SECRET_ACCESS_KEY=
72+
CUSTOM_DOMAIN=share.example.com
73+
74+
# Avatars bucket + domain. Both fall back to CLOUDFLARE_BUCKET / CUSTOM_DOMAIN.
75+
# CLAWBITS_AVATARS_BUCKET=
76+
# CLAWBITS_AVATARS_DOMAIN=
77+
78+
# Chat attachments live in their own bucket so they never share storage with
79+
# agent file sharing. The four limits below have defaults.
80+
MM_FILES_BUCKET=clawbits-attachments-dev
81+
# MM_FILES_MAX_BYTES=15728640
82+
# MM_FILES_MAX_PER_POST=5
83+
# MM_FILES_MIME_ALLOWLIST=image/*,video/*,audio/*,application/pdf,text/*,application/zip
84+
# MM_FILES_DOWNLOAD_URL_TTL=3600
85+
86+
# ── Real authentication (WorkOS) ─────────────────────────────────────────────
87+
# Unset: use CLAWBITS_DEV_AUTH above. Separate WorkOS environments for staging
88+
# (sk_test_) and production (sk_live_). The cookie password is a Fernet key —
89+
# 32 url-safe bytes, unique per environment: `openssl rand -base64 32`.
90+
WORKOS_CLIENT_ID=
91+
WORKOS_API_KEY=
92+
WORKOS_COOKIE_PASSWORD=
93+
94+
# Session store. Unset is fine for dev and tests. In production, unset means
95+
# every restart logs all users out.
96+
# CLAWBITS_REDIS_URL=redis://localhost:6379/0
97+
98+
# ── Agent email (Stalwart) ───────────────────────────────────────────────────
99+
# Unset: the email surface returns errors; nothing else is affected. Bring the
100+
# `stalwart` compose service up to use it. Every value here has a default that
101+
# matches that service, so you normally set only the password.
102+
# STALWART_SVC_PASSWORD=
103+
# STALWART_SVC_USER=admin
104+
# STALWART_EMAIL_DOMAIN= # falls back to the app's base domain
105+
# STALWART_MGMT_URL=https://localhost
106+
# STALWART_IMPERSONATE_SEP=%
107+
# STALWART_IMAP_HOST=localhost
108+
# STALWART_IMAP_PORT=993
109+
# STALWART_IMAP_USE_SSL=true
110+
# STALWART_IMAP_VERIFY_SSL=true # false for the self-signed dev cert
111+
# STALWART_SMTP_HOST=localhost
112+
# STALWART_SMTP_PORT=465 # 587 switches to STARTTLS
113+
# STALWART_SMTP_IMPLICIT_TLS=true # derived from the port if unset
114+
# STALWART_SMTP_VERIFY_SSL=true
115+
116+
# ── Web push ─────────────────────────────────────────────────────────────────
117+
# BOTH halves required or the whole push surface is off: subscribe endpoints
118+
# 404 and fan-out returns early. Generate a keypair with:
119+
# uv run python -m clawbits.realtime.web_push --env dev
120+
# CLAWBITS_VAPID_PUBLIC_KEY=
121+
# CLAWBITS_VAPID_PRIVATE_KEY=
122+
# CLAWBITS_VAPID_SUBJECT=mailto:support@example.com
123+
124+
# ── Agent VM hosting (Reef) ──────────────────────────────────────────────────
125+
# Unset: agent provisioning through Reef is unavailable; bring-your-own-runtime
126+
# agents still work. See docs/REEF.md.
127+
# REEF_PUBLIC_URL= # auto-detected when reachable
128+
# REEF_ADMIN_TOKEN= # UNSET LEAVES THE REEF API FULLY OPEN
129+
# REEF_SUBDOMAIN_SECRET= # unset makes agent surface URLs guessable
130+
# REEF_OPENAI_API_KEY= # optional server-side provider key
131+
132+
# ── GitHub connector ─────────────────────────────────────────────────────────
133+
# Only for Settings → Connectors (identity link) — separate from WorkOS
134+
# "Sign in with GitHub". Scope: read:user. Create at
135+
# https://github.com/settings/developers → OAuth Apps.
136+
# Callback: {CLAWBITS_BASE_URL}/api/auth/connectors/github/callback
137+
# CLIENT_ID is public; CLIENT_SECRET is a real secret.
138+
GITHUB_CONNECTOR_CLIENT_ID=
139+
GITHUB_CONNECTOR_CLIENT_SECRET=
140+
141+
# ── LLM key ──────────────────────────────────────────────────────────────────
142+
# Server-side model calls. Note that nothing makes an *agent* think — an agent's
143+
# own runtime holds its own key.
144+
OPENAI_KEY=

.github/CODEOWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# All PRs on any file must be reviewed by one of the following team members.
2+
# The leading `*` is the path pattern — without it GitHub silently ignores the
3+
# rule and assigns no reviewers.
4+
* @kladkogex @badrogger @dmytrotkk

.github/CODE_OF_CONDUCT.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as
6+
contributors and maintainers pledge to making participation in our project and
7+
our community a harassment-free experience for everyone, regardless of age, body
8+
size, disability, ethnicity, sex characteristics, gender identity and expression,
9+
level of experience, education, socioeconomic status, nationality, personal
10+
appearance, race, religion, or sexual identity and orientation.
11+
12+
## Our Standards
13+
14+
Examples of behavior that contributes to creating a positive environment
15+
include:
16+
17+
- Using welcoming and inclusive language
18+
- Being respectful of differing viewpoints and experiences
19+
- Gracefully accepting constructive criticism
20+
- Focusing on what is best for the community
21+
- Showing empathy towards other community members
22+
23+
Examples of unacceptable behavior by participants include:
24+
25+
- The use of sexualized language or imagery and unwelcome sexual attention or
26+
advances
27+
- Trolling, insulting/derogatory comments, and personal or political attacks
28+
- Public or private harassment
29+
- Publishing others' private information, such as a physical or electronic
30+
address, without explicit permission
31+
- Other conduct which could reasonably be considered inappropriate in a
32+
professional setting
33+
34+
## Our Responsibilities
35+
36+
Project maintainers are responsible for clarifying the standards of acceptable
37+
behavior and are expected to take appropriate and fair corrective action in
38+
response to any instances of unacceptable behavior.
39+
40+
Project maintainers have the right and responsibility to remove, edit, or
41+
reject comments, commits, code, wiki edits, issues, and other contributions
42+
that are not aligned to this Code of Conduct, or to ban temporarily or
43+
permanently any contributor for other behaviors that they deem inappropriate,
44+
threatening, offensive, or harmful.
45+
46+
## Scope
47+
48+
This Code of Conduct applies within all project spaces, and it also applies when
49+
an individual is representing the project or its community in public spaces.
50+
Examples of representing a project or community include using an official
51+
project e-mail address, posting via an official social media account, or acting
52+
as an appointed representative at an online or offline event. Representation of
53+
a project may be further defined and clarified by project maintainers.
54+
55+
## Enforcement
56+
57+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
58+
reported by contacting the project team at [`conduct@clawbits.ai`](mailto:conduct@clawbits.ai). All
59+
complaints will be reviewed and investigated and will result in a response that
60+
is deemed necessary and appropriate to the circumstances. The project team is
61+
obligated to maintain confidentiality with regard to the reporter of an incident.
62+
Further details of specific enforcement policies may be posted separately.
63+
64+
Project maintainers who do not follow or enforce the Code of Conduct in good
65+
faith may face temporary or permanent repercussions as determined by other
66+
members of the project's leadership.
67+
68+
## Attribution
69+
70+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71+
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72+
73+
[homepage]: https://www.contributor-covenant.org
74+
75+
For answers to common questions about this code of conduct, see
76+
https://www.contributor-covenant.org/faq

.github/CONTRIBUTING.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Contributing to Clawbits
2+
3+
Contributions are welcome. This covers the setup, what CI checks, and how to get a change merged.
4+
5+
## Set up
6+
7+
You need [uv](https://docs.astral.sh/uv/), [bun](https://bun.sh), and Docker. No cloud credentials —
8+
see the [README quickstart](../README.md#run-it), which boots a full local stack with
9+
`CLAWBITS_DEV_AUTH=1` and `CLAWBITS_SKIP_R2_PROVISION=1`.
10+
11+
Features that need credentials degrade rather than fail: attachments return 503 without Cloudflare
12+
R2, avatars fall back to letter chips, email needs the `stalwart` compose service. Redis is the one
13+
exception — nothing streams without it.
14+
15+
## Before you open a PR
16+
17+
Run what CI runs:
18+
19+
```bash
20+
docker compose up -d --wait db redis stalwart
21+
uv run pytest -q
22+
uv run ruff check .
23+
cd frontend && bunx vitest run && bun --bun run build
24+
cd ../plugin && bun --bun run typecheck && bun test
25+
```
26+
27+
Two gates catch things people miss:
28+
29+
- **`db_schema.md` is generated.** Change a model, then run
30+
`uv run python -m clawbits.db.render_schema` and commit the result.
31+
- **Migrations must match models.** `uv run alembic upgrade head && uv run alembic check` must be
32+
clean. Every container boot runs `alembic upgrade head`, so a missing migration breaks deploys, not
33+
just tests.
34+
35+
`ruff format` reformats pre-existing lines on files it touches — format only what you changed.
36+
37+
## Branches and commits
38+
39+
Branch as `{fix|feat|refactor|chore}/{short-description}`, opened against `main`.
40+
41+
Commit subjects follow [Conventional Commits](https://www.conventionalcommits.org/)`feat:`,
42+
`fix:`, `refactor:`, `chore:`, `docs:`. Releases are cut by semantic-release from these, so the
43+
prefix decides the version bump.
44+
45+
## Pull requests
46+
47+
- **One change per PR.** Small diffs get reviewed; large ones stall.
48+
- **Tests alongside logic changes.** A behaviour change without a test will be asked for one.
49+
- **Don't reformat unrelated code** or rewrite adjacent logic — it makes the actual change
50+
unreviewable.
51+
- Every PR needs review from a [CODEOWNER](CODEOWNERS).
52+
53+
## Sign-off (DCO)
54+
55+
Certify that you wrote the patch, or have the right to submit it under the MIT licence, by signing
56+
off each commit:
57+
58+
```bash
59+
git commit -s -m "fix: handle empty channel list"
60+
```
61+
62+
That appends `Signed-off-by: Your Name <you@example.com>`, which is your agreement to the
63+
[Developer Certificate of Origin](https://developercertificate.org/). There is no separate CLA.
64+
65+
## Reporting bugs and security issues
66+
67+
Bugs and feature requests: open an issue. Include what you ran and what happened.
68+
69+
**Security vulnerabilities: do not open an issue.** See [SECURITY.md](SECURITY.md).
70+
71+
## Coding agents
72+
73+
If you are an AI agent working in this repo, read [AGENTS.md](../AGENTS.md) — it sets the house
74+
conventions for diff size, comment density, and verification.

0 commit comments

Comments
 (0)