Commit Graph

23 Commits

Author SHA1 Message Date
leetcrypt
65df12de9e feat(ai): model profiles, capability discovery, and agentless /ai list|models
Make connecting any model a config step, not a code change:
- models.toml named profiles (api_key_env names an env var, never the key)
- providers gain available_models(); add preflight + --list-models/--check
- /ai list and /ai models in-room; client probes local Ollama for
  /ai models when no agent is running, and /ai list hints to summon one
- docs/providers.md provider guide + examples/echo_provider.py
- README: command table, AI section, layout updated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 15:25:07 -07:00
leetcrypt
05bdc2d802 feat(ai): /ai start|stop agent control + in-room typing indicator
Owner of the spawning client can summon/dismiss a local AI agent from inside
the room (default ollama/qwen2.5:3b); the agent emits encrypted typing frames
that drive a "thinking" spinner in the client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 11:38:15 -07:00
leetcrypt
54b7637ec8 feat(agent): model-agnostic AI agent bridge (PoC) + pin lets-hack demo to main
Add cmd_chat/agent: a headless client that joins a room via SRP, decrypts
broadcasts, and answers /ai <question> through a pluggable model provider
(ollama default + anthropic + openai-compatible + module:Class). Server and
zero-knowledge guarantees unchanged; the agent is just another encrypted client.

Also pin the lets-hack demo to a detached worktree of main (default) so running
it from dev still demos stable main without touching the working checkout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-01 02:05:48 -07:00
leetcrypt
5de493e895 feat(hh): /pw command, RAM-only direnv autostart, robust lets-hack; coven→clergy
- add /pw (alias /password): reveal this room's password locally (never
  broadcast); surfaced in the F1 help overlay and the join hint
- direnv-autostart/: cd-to-launch a single real-user session via direnv;
  password is minted in memory at launch (never written to disk, matching the
  RAM-only model) and scoped to the child process. setup.sh installs direnv,
  hooks bash/zsh, and `direnv allow`s the dir
- lets-hack.sh: boot a FRESH server by default (replacing any live one) with a
  --reuse opt-out; add -h/--help/-help; guard against killing the tmux session
  you're attached to; switch-client into the coven when run inside tmux
- rename coven→clergy across rust/python/scripts; tests/test_coven.py→test_clergy.py
- snapshots in-progress hack-house client work (sandbox, themes, net, ui)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-31 22:29:17 -07:00
leetcrypt
82a04f3e12 feat(coven): SRP/Fernet crypto parity + multi-user coven foundation ⛧
Begin the coven evolution of cmd-chat (see docs/spec-collaborative-sandbox.md):
a Rust/ratatui client for the unchanged Python Sanic server, plus the
multi-user + zero-knowledge groundwork.

P0 — crypto parity (the spec's #1 risk), proven three ways:
- Hand-rolled SRP-6a (NG_2048, SHA-256, rfc5054 padding) matching pysrp
  byte-for-byte, incl. the fixed b"chat" SRP identity and minimal-vs-256B
  width quirks. Golden-vector unit test + offline selftest.
- Live handshake against the running server (H_AMK verified).
- Cross-language E2E: Python client decrypts a Rust-encrypted Fernet message.

P2 — multi-user coven (server):
- CMD_CHAT_MAX_USERS capacity cap (default 4, infra-for-more).
- Authoritative roster + user_joined broadcasts.
- Free the slot/username on ws disconnect (was held until 1h stale sweep).

Also: fix requirements.txt (was UTF-16, unparseable by pip).

coven/ : Rust crate (crypto.rs proven; main.rs spike CLI: selftest/handshake/srpm)
docs/  : full feature spec for the 6 requested features.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 11:47:25 -07:00
leetcrypt
70ddca8a1f feat: encrypted file transfer with propose/accept flow
New commands: /send <filepath>, /accept, /reject

Protocol:
- Sender proposes file (name, size, SHA-256 hash)
- Recipient sees offer and chooses /accept or /reject
- On accept: file chunked (64KB), encrypted with room key, sent over WebSocket
- On receive: chunks reassembled, SHA-256 verified, saved to ./downloads/
- Server never sees file content (E2E encrypted, same as messages)

Limits: 50MB max file size. Files saved with collision-safe naming.
No server changes — server remains a dumb encrypted relay.

All 79 existing tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 00:01:51 -07:00
leetcrypt
e7bacc93da fix(security): comprehensive security hardening — TLS, HMAC WS auth, rate limiting, IP leak prevention
CRITICAL fixes:
- Auto-generated self-signed TLS certs (HTTPS/WSS by default)
- Removed session_key from /srp/verify response (was sent in plaintext)
- Replaced with HMAC-SHA256 ws_token for WebSocket authentication

HIGH fixes:
- WebSocket auth now validates ws_token via hmac.compare_digest()
- /clear endpoint requires Bearer admin_token (printed at server start)
- Password no longer required as CLI arg — supports env var + getpass prompt
- Removed user_ip from Message model (no longer broadcast to clients)

MEDIUM fixes:
- Rate limiter on /srp/init and /srp/verify (10 req/min/IP)
- MessageStore capped at 1000 messages (prevents RAM DoS)
- access_log disabled (was leaking request metadata)

LOW fixes:
- Username sanitization against rich markup injection
- Dead code removed from helpers.py

All 79 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-25 20:30:40 -07:00
mirai
467d942877 New storage scheme 2026-01-06 21:42:50 +08:00
mirai
264d19e932 NO LOGS 2026-01-03 12:00:52 +03:00
mirai
0756aab53f Final notes 2026-01-02 23:25:02 +03:00
mirai
5cbe355660 feat: add SRP authentication, improve security
- Replace RSA key exchange with SRP (Secure Remote Password)
- Password never transmitted over network
- Add unit tests for endpoints
- Fix datetime.UTC compatibility for Python < 3.11
- Fix logger.exception usage
- Update README with new auth flow diagram
2026-01-02 23:09:00 +03:00
mirai
95f8a192b5 feat: complete client-server architecture refactoring
Server:
- Split into views, routes, helpers, models modules
- Merged /ws/talk and /ws/update into single /ws/chat endpoint
- Replaced polling with push-based broadcast model
- Added username uniqueness validation on connect
- Fixed run_server arguments bug (workers parameter)
- Removed deprecated loop argument from Sanic listeners
- Replaced datetime.utcnow() with timezone-aware datetime.now(timezone.utc)

Client:
- Rewrote client as single-file module
- Migrated from websocket-client to websockets (asyncio)
- Fixed websocket-client conflict with asyncio event loop on Windows
- Added progress indicators for key generation, exchange, connection
- Added animated 3D spinning cube in UI
- Updated RSA key from 512 to 2048 bits

CLI:
- Removed unnecessary asyncio.run() wrapper
- Simplified entry point
2026-01-02 14:42:33 +03:00
mirai
6411df575e Updated to modern version of Optional type 2025-11-18 10:46:15 +04:00
mirai
64b0967292 Fix renderer typing, preserve message text, and harden crypto key handling
Fix abstract renderer signatures and add small stubs so type checkers can
see expected attributes (e.g. username, _decrypt). This removes several
mypy false-positives that were caused by mixin/ABC mismatches.
Preserve message text containing ':' by using split(':', 1) in both
DefaultClientRenderer and RichClientRenderer.
Normalize renderer APIs: print_chat(...) now takes the response mapping
and returns None (matches runtime behavior).
Make RSA symmetric-key request more robust: read r.content instead of a
fixed-size r.raw.read(999), avoiding truncated key material.
Improve _connect_ws exception handling in client to ensure a valid
Exception is re-raised if connection attempts fail.
Correct server/service typing: memory_msgs is now typed as
list[Message] and we null-check incoming payload text before creating a
new Message.
Replace manual package list in setup.py with setuptools.find_packages()
so packaging uses valid Python package names.
Installed types-requests in the project venv so mypy no longer flags the
requests import.
Verification: ran python -m compileall and mypy cmd_chat — no issues
remain.
Notes:

Wire format still uses Python literal evaluation in some places (existing
behavior); switching to JSON for client/server payloads is recommended as a
follow-up for robustness and security.
2025-11-05 19:29:24 +05:30
mirai
c3467b89ae removed temporary files 2025-10-03 21:08:43 +03:00
mirai
82a78e7053 Update client.py 2025-10-03 20:58:44 +03:00
mirai
b0ff612023 Password update 2025-09-10 19:58:59 +03:00
mirai
6a044ecaf8 Working on 1.1.22 2023-12-03 16:18:09 +03:00
mirai
316a0e3e1e Reworked setup.py, now you can run cmd_chat directly. Reworked sanic http webserver to make it work. Update readme, etc... 2023-11-27 14:30:01 +03:00
mirai
c5fa982f65 Add CLI run options, update README 2023-11-27 06:50:16 +03:00
mirai
8c4799c634 Removed eval, fixed security vulnerability 2023-11-27 05:45:45 +03:00
mirai
4554d76d0b PyPi Update 2023-03-08 19:26:21 +03:00
mirai
a8f296c0f1 Code refactoring 2023-03-08 18:59:38 +03:00