I build technology where human behavior, data, cloud infrastructure, and practical engineering meet. Psychology helps me understand the people; engineering lets me build for them.
Right now I am a School Lead Educator at TechLit Africa, leading hands-on digital literacy learning. Before that I was a Backend Developer Intern at Chakula Africa, building REST APIs and forecasting workflows for agricultural platforms.
| Psychology taught me to ask | Engineering taught me to ask |
|---|---|
|
|
flowchart TD
P["Psychology<br/>how people actually behave"] --> F{"Where is<br/>the friction?"}
F --> S["Systems thinking"]
S --> B["Backend engineering"]
S --> A["AI products"]
S --> E["Education"]
B --> U(["Software that makes sense to people"])
A --> U
E --> U
| Found in my repositories | |
|---|---|
| Languages | HTML · Python · CSS · JavaScript · C · TypeScript · Ruby |
| Backend | FastAPI · SQLAlchemy · Pydantic · Django · Express · SQLModel |
| Frontend | React · Vite · Tailwind CSS |
| Data & databases | PostgreSQL · MongoDB |
| Testing | pytest · Vitest |
| Infrastructure | GitHub Actions · Railway · Docker · Docker Compose |
Detected automatically from 30 repositories (public and private) · last changed 2026-10-26
| Area | What I work with |
|---|---|
| Backend & systems | Python · FastAPI · Django · Django REST Framework · PostgreSQL · SQL · authentication and business logic · API design |
| Frontend | React · TypeScript · Vite · HTML · CSS · JavaScript · interfaces that explain themselves |
| Cloud & infrastructure | AWS (Certified Cloud Practitioner) · Docker · Railway · Supabase · DigitalOcean · Linux · Git and GitHub workflows |
| Testing & delivery | pytest · Vitest · GitHub Actions · automated checks before every deploy |
| AI & data | LLM-powered applications · RAG systems · AI assistants · forecasting · data pipelines · human-AI interaction |
| Product & research | User-centered design · systems thinking · behavioral analysis · research-driven problem solving |
HTML · Python · CSS · JavaScript · C · TypeScript · Ruby
%%{init: {"themeVariables": {"pieSectionTextSize": "0px"}}}%%
pie title Share of code across my repositories
"Python · 42.6%" : 1161.8
"TypeScript · 21.4%" : 583.1
"JavaScript · 21.2%" : 577.2
"CSS · 8.4%" : 230.2
"HTML · 3.7%" : 101.1
"C · 2.3%" : 62.7
"Ruby · 0.4%" : 10.1
|
Weather apps report conditions. This asks what those conditions mean for a person: live weather becomes a mood score with the reasons behind it, a week-ahead outlook, and a verdict on whether the weather suits your plans.
|
A computer lab management system for schools. It replaces scattered spreadsheets with one connected place for students, classes, timetables, attendance, equipment, weekly targets, and reports, and gives each school its own private workspace.
Built for the school computer lab I lead · source is private |
|
Mental-health support for young people in Kenya: therapy and peer counselling with vetted professionals, sessions booked around their calendars, private check-ins and journaling, and an AI companion whose crisis reply never depends on the AI being up. It began in 2025 as MindConnect, built with a team; in October 2026 I kept building it on my own as v2.
Source · v1, built with a team |
A backend connecting agricultural knowledge, AI assistance, and decision support. Deliberately practical: useful output over impressive automation.
Built at Chakula Africa · source is private |
Lately
| Project | Last change | What changed |
|---|---|---|
| Healing Hive | 2026-10-23 | Say which commit the live API is running in /health |
| MoodForecast AI | 2026-10-23 | Keep local files out of the Docker image and run it unprivileged |
| Murengeti Lab System | 2026-10-23 | Put getData's comment back above getData, where adding unavailableMessage had left it behind |
Read from each project's repository several times a day.
Research and community
- Personality and friendship selection research — worked in a five-person team, coordinated survey collection from 150+ respondents, and led the analysis.
- Millennium Fellowship, Art Therapy Clubhouse — co-led a team supporting 40+ youth through an art therapy initiative.
- Mathematics Olympiad — placed third regionally; analytical problem-solving was already part of the story.
timeline
2021 : BA Psychology begins at Kenyatta University
2023 : Student Attache at KEMRI VCT
2024 : ALX Software Engineering begins
: Student Psychologist at Mathari Teaching and Referral Hospital
: Class Representative at Kenyatta University
2025 : AWS Certified Cloud Practitioner
: BA Psychology completed
: Technical Apprentice with TechLeap at Zynamis
2026 : Backend Developer Intern at Chakula Africa
: School Lead Educator at TechLit Africa
AI agents and agentic systems · backend architecture at scale · LLM-based products · cloud-native engineering · reliable ETL and forecasting workflows · API security · and the human questions that appear once a technical system reaches real users.
Beyond code, I am usually thinking, writing, drawing, or learning about psychology, creativity, and human connection.
kathfk1234.github.io/KathFK1234 is a working terminal. Type help, or try these:
| Try | What happens |
|---|---|
about · projects · skills · experience |
the short version of this page |
ls · cd projects/moodforecast-ai · tree |
browse real folders of notes and project write-ups |
cat README.md · grep friction · find mood |
read and search them |
mood nairobi · mood week tokyo · mood nairobi vs reykjavik |
live readings from the MoodForecast AI service: today's mood score and why, the week ahead, or two places side by side |
mood picnic in cape town · mood activities mombasa |
whether the weather suits a plan, and what is practical somewhere right now |
mood · mood surprise · mood api |
places to try, a place picked for you, and everything the service can do right now |
man mood · man grep |
a manual for every command, with examples you can click |
theme · font · crt |
change how the terminal looks |
stack |
languages and tools measured across my repositories |
updates · updates healing-hive |
the latest work on each project, read from its repository |
fortune · neofetch · coffee · sudo hire-me |
for the curious |
Tab completes commands and paths, Shift+Tab leaves the prompt for the links and buttons, ↑/↓ revisit history, and any highlighted command can be clicked or tapped. Add ?cmd=projects to the URL to open the page with a command already run.
How it is built, and how to run it
Vite + React + TypeScript. The terminal's file system is the real content/home/ folder: add a file there and it appears in ls, cat, grep, find, and tree.
- A file named
_aboutholds the one-line description of the folder it sits in. - Any other file starting with
_shows up as a hidden dotfile (_secretsbecomes.secrets, visible withls -a). - Commands live in src/shell/commands.tsx;
helpandmanare generated from that list.
npm install
npm run dev # local server with live reload
npm test # shell, file system, and completion tests
npm run build # type-check and build into dist/
python3 -m venv .venv # for the Python scripts below, once; a distribution's own Python refuses pip installs
. .venv/bin/activate # in each new shell
pip install --require-hashes -r requirements.txt # the same pinned versions the workflow usesPushing to main builds and deploys the site through .github/workflows/deploy.yml. In the repository settings, Pages → Source must be set to GitHub Actions.
Languages and tools update themselves. Several times a day (or on demand from the Actions tab → Run workflow), the same workflow runs languages_update_script.py. It reads every repository I own (the public ones, and the private ones too once the STACK_TOKEN secret described below is set, as it is here) — GitHub's language statistics, plus dependency files such as requirements.txt, pyproject.toml and package.json — and rewrites:
- the icon row, tools table, language list and pie chart in this README (between the
stackandlanguagescomment markers), and - src/data/stack.json, which the site's
skillsandstackcommands read.
The On GitHub card is the contribution calendar from my profile page, in this site's colours: activity_card_script.py asks GitHub for the past year and uses the same days, the same counts and GitHub's own shade for each day. It is drawn on every run of the workflow, each push included, and published with the site instead of being committed, so the README always shows the newest one. GitHub caches images for a few minutes, so a fresh contribution can take a little while to appear.
The mood command keeps up with MoodForecast AI. Nothing about that service is written into the terminal by hand more than once:
- Each visit,
moodfirst asks the live service what it offers (its OpenAPI description). EveryGET /api/<name>/{location}endpoint is usable at once asmood <name> <place>, every otherGET /api/<name>asmood <name>, and any field a response gains is shown, even before the terminal has a tailored view for it.mood apilists what it found. - What the service says is passed on as it says it: its own error explanations, its questions about other places, its place suggestions when a name is mistyped, and its current list of activities (used for suggestions and Tab completion the same day one is added).
- The scheduled run also executes mood_sync_script.py, which reads the endpoints plus the place lists and activities in the moodforecast_ai repository and writes src/data/mood.json. The terminal uses it for suggestions ("where next?"), Tab completion, and as a fallback when the service does not answer. The same run rewrites the endpoint list visitors can read in the terminal (
cat ~/projects/moodforecast-ai/API.md).
Project write-ups keep up with the projects. The same scheduled run executes projects_sync_script.py, which reads the history of every project listed at the top of that script and rewrites:
- the Lately table under Featured work (between the
projectscomment markers), and each project's source link, which turns into "source is private" on its own if a repository is made private, - src/data/projects.json, which the terminal's
updatesandprojectscommands read, and - a
CHANGELOG.mdin each project's folder under content/home/projects/, readable in the terminal withcat.
A private repository's commit messages stay out of all three unless its entry in the script says "share": True; otherwise only its dates and commit count are shown.
Dates and commit lists look after themselves; the paragraphs I wrote about a project do not. So the script also records the commit each write-up was last revised at (projects_reviewed.json) and reports what has changed since. The scheduled run posts that as a notice on the workflow, and on my own machine the same check runs against the local clones, where it also sees work that is not pushed yet:
python3 projects_sync_script.py --check # ask GitHub (GITHUB_TOKEN needed for private projects)
python3 projects_sync_script.py --check --local .. # ask the clones next to this one
python3 projects_sync_script.py --mark-reviewed # after revising the write-upsTo add a project, add a line to PROJECTS in the script and a folder for it under content/home/projects/.
To try MoodForecast AI changes that are not merged or deployed yet, run its backend locally and point both halves at it:
python3 mood_sync_script.py --source ../moodforecast_ai --api http://localhost:8000 # places, activities, endpoints
echo 'VITE_MOOD_API=http://localhost:8000' > .env.local # the site's live calls
npm run dev(git checkout src/data/mood.json content/home/projects/moodforecast-ai/API.md puts the generated files back afterwards.)
The scheduled run commits its changes to main, so git pull before starting new work.
Including private repositories. By default only public repositories are scanned. To count private ones too, create a fine-grained personal access token (GitHub → Settings → Developer settings → Fine-grained tokens) with All repositories access and read-only Contents and Metadata permissions, then save it in this repository under Settings → Secrets and variables → Actions as a secret named STACK_TOKEN. Only totals are published — language sizes and tool names — never private repository names, which are also kept out of the workflow logs.
Only tools named in KNOWN_PACKAGES / KNOWN_FILES at the top of the script are reported; add a line there to teach it a new one. To run it by hand:
python3 languages_update_script.py --dry-run # preview
python3 languages_update_script.py # rewrite README and stack.jsonI like working with people who are building thoughtful products, solving difficult problems, and asking deeper questions. If that sounds like you, let’s talk.


