Metadata-Version: 2.4
Name: fens-thinking-machine
Version: 0.1.0
Summary: Fen's Thinking Machine — RetroCodeRamen autonomous coding harness for local Ollama
Author: RetroCodeRamen
License: MIT
Project-URL: Homepage, https://github.com/RetroCodeRamen/fens-thinking-machine
Project-URL: Repository, https://github.com/RetroCodeRamen/fens-thinking-machine
Project-URL: Issues, https://github.com/RetroCodeRamen/fens-thinking-machine/issues
Keywords: ollama,agent,coding,fen,harness,autonomous
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: tomli>=2.0.1; python_version < "3.11"
Requires-Dist: tomli-w>=1.0.0
Requires-Dist: cryptography>=42.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# 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](https://github.com/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

```bash
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

```bash
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.

```bash
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.

```bash
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):

1. **Outline** — invent up to `plan_max_sections` planning sections (ceiling, not a fill quota)
2. **Sections** — plan each section into small features + checkpoints
3. **Cohesion** — one final review so ids/verify commands fit together

Writes `FTM/PLAN_OUTLINE.md` plus the usual `PLAN.md` / `features.json` / `checkpoints.json`.

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

```bash
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/ runbooks
- `fen schedule --worker|--tick` — Fen scheduler
- `fen stop` / `fen stop now` / `fen build stop` / `fen work stop`
- `fen plan ["…"]` / `fen build` / `fen start` — launch jobs (detached by default)
- `fen report` / `fen current` / `fen watch` — live job awareness
- `fen status` / `fen quest` / `fen check` / `fen explain`
- `fen 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 share`
- `fen notify on|off` / `fen update` / `fen migrate` / `fen completion bash|zsh|fish`
- `fen config` / `fen host` / `fen key` / `fen credential` / `fen freellm` / `fen knowledge`
- `sudo fen build --foreground` — elevated (only if `allow_elevated=true`)

### Shell tab completion

```bash
eval "$(fen completion bash)"   # or: fen completion zsh / fish
```

### Safety / budget knobs

```bash
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)

```bash
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.
