3.7 KiB
sjcode
ein terminal coding agent, der die ollama API nutzt
Setup
cp config.toml.example config.toml # then edit port / model / limits
python3 server/server.py # starts the daemon + admin CLI
config.toml is machine-local and git-ignored; config.toml.example is the
template. On first start the daemon creates the SQLite database (sjcode.db).
Daemon (server.py)
On startup it prints its settings and drops into a minimal admin CLI (accounts are stored in SQLite):
| command | effect |
|---|---|
create <name> [role] |
create account (asks for password, default role user) |
list |
show all accounts |
delete <name> |
remove account |
role <name> <role> |
change role |
passwd <name> |
set a new password |
usage [name] |
used minutes today vs. limit |
reset [name] |
reset the daily usage counter |
status |
show daemon settings |
quit |
stop the daemon |
While the CLI runs, an HTTP API is served in the background:
POST /login—{"username", "password"}→{"token", ...}POST /chat—{"token", "message", "model"?}→{"response", ...}GET /models?token=...— list ollama models
Every user row stores: username, password_hash, last_logged_in,
role, used_today (minutes of AI usage; resets on a new day).
Roles and limits
In config.toml each role gets a daily limit in minutes:
[limits]
user = 120 # default role for new accounts
admin = -1 # negative = unlimited
Login and every chat request are blocked once used_today reaches the limit.
Client (client.py)
./coder # or: python3 client.py
python3 client.py 10.0.0.5:8420 # explicit daemon address
python3 client.py --model qwen3-coder # skip the model picker
python3 client.py --no-probe # skip the reachability check (use behind
# HTTP proxies that answer on every port)
On start the client asks which server to connect to: pick one of the saved
ones, or add a new one (n). Every server you use is saved in
~/.config/sjcode/client.json together with the username and the last
model, so the next start is just Enter-Enter. Addresses without a port use
8420; host:port, http(s)://... URLs and IPv6 literals are accepted.
After login and model choice you get the agent banner and a chat REPL. Commands:
| command | effect |
|---|---|
/help |
list commands |
/server |
show the connected server |
/models |
list models on the server |
/model <n> |
switch model (saved for this server) |
/limit |
remaining minutes today (last known) |
/clear |
forget the conversation history |
/quit |
exit |
Anything else is sent to the model. The client keeps the last few turns as
context (the daemon API itself is stateless) and renders the reply in the
agent style (✓ lines for actions the model reports).
Requirements
- Python 3.11+ (stdlib only;
tomllibis included) - ollama listening on the address from
config.toml