Fen's Thinking Machine — RetroCodeRamen autonomous coding harness for local Ollama
Project description
Fen's Thinking Machine
Hey — I'm Fen (the frog). I'm on the RetroCodeRamen team, and this is the little coding harness we built so you can point a model at a project and actually ship something without babysitting a chat window forever.
Plan with me. Build in a fresh-context loop. Talk to me when you get stuck. Local Ollama, cloud models, or a free-LLM pool — whatever you've got in the garage.
GitHub: RetroCodeRamen/fens-thinking-machine
I don't worship tooling. I poke at it until it makes sense, then I show you how it works. If this was "supposed to be a weekend project"… yeah. Welcome.
Install
pip install fens-thinking-machine
# or from this repo:
uv venv && uv pip install -e .
# global tool (nice):
uv tool install -e .
CLI entry point: fen — that's me on your path.
Quick start
fen config
# Step 0: checks Python packages (cryptography, tomli-w), git, curl — offers to install gaps.
# No Groq/OpenAI SDKs required — cloud APIs are plain HTTP.
# Ollama: pick remote box, or install+pull on this Linux machine.
# CPU recipe (7B + num_ctx): docs/CPU_OLLAMA.md
# Feeling nervous? fen doctor
fen host add garage http://YOUR-OLLAMA-HOST:11434 --model coding7-long
fen host use garage
fen config set eval_enabled false # small CPU RAM hosts: skip the second brain
fen config set num_ctx 12288
fen config set num_thread 8
# Or Google Gemini (cloud — much faster than a lonely CPU box):
fen credential set GOOGLE_API_KEY # prompts; encrypted under ~/.ftm/
fen host add google --provider google --model gemini-3.5-flash
fen host use google
fen new project TodoLib "Tiny Python add(a,b) library with pytest"
# optional: --template cli|library|desktop|webapi
cd ~/FTM\ Projects/TodoLib # or whatever projects folder you picked
fen plan # launcher (detached); uses DESCRIPTION if no prompt
fen build # returns your shell; logs under FTM/logs/
fen report # follow the log (Ctrl+C detaches; job keeps going)
fen talk # ask me what's going on — I'm the curious one, not the expert on a mountain
Projects folder
First run, I'll ask where to keep projects (default suggestion: wherever you launched fen from). No hard-coded ~/FTM Projects for fresh installs. Existing configs stay put.
fen config set projects_dir "/path/you/choose"
fen new project MyApp "What the app should do"
Work runbooks (recurring jobs)
Inside a project, WORK/<name>/ is for recurring runbooks — separate from plan/build in FTM/. Saturday "fix a button," somehow also "run the blog every morning." Scope? Never heard of her.
cd /path/to/TechBlog
fen work plan daily # wizard: goal, steps, how often
fen work run daily # arm fen-scheduler.service
fen work once daily # one cycle now
fen work status
fen work stop daily # soft + disarm next fire
fen work stop daily now # kill + disarm
fen schedule --worker # foreground scheduler (or systemd user unit)
Stop hierarchy: fen stop soft-stops build+work and disarms next work fires; fen stop now hard-kills all. Scoped: fen build stop / fen work stop (+ optional now).
Talk: describe a setup and I'll propose fen … commands, then wait for you to confirm before anything runs. Okay, so technically you could type them yourself. But look — this way's more fun.
Checkpoints / layered planning
fen plan defaults to layered mode (friendly to lightweight local models):
- Outline — invent up to
plan_max_sectionsplanning sections (ceiling, not a fill quota) - Sections — plan each section into small features + checkpoints
- Cohesion — one final review so ids/verify commands fit together
Writes FTM/PLAN_OUTLINE.md plus the usual PLAN.md / features.json / checkpoints.json.
fen config set plan_layered true
fen config set plan_max_sections 3
fen config set plan_cohesion false # skip slow layer-3 on CPU; merge still works
fen config set plan_layered false # legacy monolith + plan_review_passes
fen config set plan_review_passes 3 # only used when layered=false
fen config set stop_at_checkpoints true # pause after each checkpoint for review
fen config set stop_at_checkpoints false # run through to the goal
fen config set stream true # live token + tool output (default on)
fen config set num_thread 8 # CPU Ollama: force parallel decode threads
fen config set num_ctx 12288 # Ollama context window (0 = Modelfile default)
fen config set context_budget_chars 12000 # slim build prompt pack (BRIEF/STATUS, not full plan)
Each build iteration gets a fresh context. Continuity is FTM/BRIEF.md (auto-written) + project STATUS/docs + git — not an endless chat transcript. The builder can leave a short note with the update_handoff tool. Broken prototype? That's just the version that taught us what to change.
Verify / bash tools prepend the project root to PYTHONPATH and prefer .venv on PATH, so python3 -m pytest -q works for flat layouts without ceremony.
When paused: review, then fen build again to continue.
Jobs (default): fen plan / fen build / fen start launch in the background and return your shell. Watch with fen report / fen current / fen watch. Ctrl+C on report/watch detaches only. Soft stop: fen stop. Hard kill: fen stop now. Build-only soft: fen build stop / fen pause. Attached/debug: fen build --foreground.
CPU Ollama hosts: docs/CPU_OLLAMA.md (REMOTE pull/create vs LOCAL fen config).
Unattended "keep going": fen config set stop_at_checkpoints false, raise max_iterations, run fen build. Go make tea. Or invent an OS. Your call.
Layout
| Path | Purpose |
|---|---|
~/.ftm/config.toml |
Global config & named hosts |
~/.ftm/credentials.vault |
Encrypted named secrets (Fernet) |
~/.ftm/api_keys.vault |
Encrypted free-LLM pool keys (same vault.key) |
~/.ftm/vault.key |
Vault encryption key — back it up or secrets are unrecoverable |
~/.ftm/schedule.toml |
Armed fen work workflows |
~/.ftm/knowledge/ |
Cross-project STYLE + project index |
<projects_dir>/ |
New-project root (chosen on first run) |
<project>/FTM/ |
Plan/build harness (commit this) |
<project>/WORK/<name>/ |
Recurring work runbooks |
Secrets
Named credentials (GOOGLE_API_KEY, GITHUB_TOKEN, …) live in ~/.ftm/credentials.vault. Free-LLM pool keys live in ~/.ftm/api_keys.vault. Both use the same ~/.ftm/vault.key (Fernet, mode 0600).
fen credential set GOOGLE_API_KEY # prompts — preferred (no shell history)
fen credential status
fen key add groq # prompts into api_keys.vault + live test
fen key model groq qwen/qwen3.6-27b # pin Groq chat model for the pool
fen key test groq # re-test latest stored key
fen key status
Threat model (plain talk): encryption stops casual peeking, accidental commits, and world-readable home files. It does not stop malware or anyone who can read both a vault file and vault.key. Lose vault.key → re-enter keys. Prefer prompt forms over fen … SECRET on argv.
Legacy plaintext credentials.toml / api_keys.toml migrate into the vaults on first load/save.
Commands
fen work plan|run|stop|once|status|list|show— recurring WORK/ runbooksfen schedule --worker|--tick— Fen schedulerfen stop/fen stop now/fen build stop/fen work stopfen plan ["…"]/fen build/fen start— launch jobs (detached by default)fen report/fen current/fen watch— live job awarenessfen status/fen quest/fen check/fen explainfen pause(alias build stop) /fen hint "…" [--sticky|--after-fail]fen talk/fen ask "…"— chat with me (propose + confirm fen commands)fen profile/fen memory— global prefs under~/.ftm/user/fen projects/fen focus <id>/fen undo/fen clean/fen sharefen notify on|off/fen update/fen migrate/fen completion bash|zsh|fishfen config/fen host/fen key/fen credential/fen freellm/fen knowledgesudo fen build --foreground— elevated (only ifallow_elevated=true)
Shell tab completion
eval "$(fen completion bash)" # or: fen completion zsh / fish
Safety / budget knobs
fen config set verify_timeout_sec 300
fen config set verify_sandbox true # scrub proxies + CPU soft limit on verify
fen config set hooks_enabled true # FTM/hooks/on_*.sh
fen config set diff_max_files 20 # 0 = off; over budget → fen pause
fen config set diff_max_lines 800
fen config set pool_max_switches_per_iter 3 # then fall back to Ollama
fen config set research_enabled true # keyless DuckDuckGo web_search + fetch_url
fen notify on # desktop toast when a job exits
Local only (no Google→Ollama failover)
fen local # pin Ollama + failover off + clear sticky window
fen failover status
fen failover off # stay on cloud/pool even on 429/503
fen failover clear # drop sticky mid-window; retry cloud
fen failover on
Copy FTM/hooks/on_complete.sh.example → on_complete.sh to run custom scripts. fen undo --yes soft-restores the previous fen git checkpoint (refuses while a job runs).
Plan/build can web_search / fetch_url when docs are unclear (research_enabled; disable for air-gap).
Why this exists
Learn how things work. Make things yourself. Keep technology fun. Share what you learn. Don't be afraid to build something weird.
I'm not the genius with all the answers — I'm the frog willing to open the box and find out. RetroCodeRamen built this so you can do the same with a coding agent that doesn't need permission to be interesting.
License
MIT — poke around, remix it, show a friend how it works.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fens_thinking_machine-0.1.0.tar.gz.
File metadata
- Download URL: fens_thinking_machine-0.1.0.tar.gz
- Upload date:
- Size: 160.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
747c3f4193374b7ffb5eef664f8bab468fbf7da3dbcc1dcda37237a3376ac6f6
|
|
| MD5 |
ce0b99f341f6a6e65bbc3c771dfc1096
|
|
| BLAKE2b-256 |
d02547bcdcbf8f9415d06f38a70920f0ce0a6ca109a3a27f7606cdb67cf5c5e4
|
File details
Details for the file fens_thinking_machine-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fens_thinking_machine-0.1.0-py3-none-any.whl
- Upload date:
- Size: 168.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"KDE neon","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1dba32b759e19a69baa9f6416be89783f478200746846cd4f27a368e8d6f97a6
|
|
| MD5 |
d7208571a5740eff0b3bd29dc37eedfc
|
|
| BLAKE2b-256 |
06f0c44383df0586f5d2155254d0179929dddeae27fc1239b15be0d25cc31967
|