# Rayane Saboundji β€” rasaboun.me > Developer building products and prototyping AI solutions. TypeScript and React on the > product side, Python and PyTorch on the model side. Heavy experimentation with models: > fine-tuning on text and image, local inference, small models, multimodal. Went through > 42 Paris. Ships iOS apps, CLI tools and open-source contributions to ML tooling. The site itself is a single page whose project cards are client-rendered React islands, so this file is the full text content in a crawlable form. Projects below are the same eleven cards, in page order. - GitHub: https://github.com/Rasaboun - LinkedIn: https://linkedin.com/in/rayane-saboundji ## About Here is what I do day to day: I build products and prototype AI solutions. Mostly TypeScript and React on the product side, Python and PyTorch on the model side. I experiment a lot with models: fine-tuning on text and image, local inference, small models, multimodal… In practice that means LoRA training runs on Qwen-Image, Flux and Hi-Dream for image, and Qwen, Gemma and LFM for text, plus [needle-transit](https://github.com/Rasaboun/needle-transit), a 26M-parameter fine-tune that turns a transit question into a single tool call and runs in the browser. I also build my own apps, notably [Plocket](https://getplocket.app) and [Gourmand](https://gourmand.app/), an iOS recipe app built with React Native. And I contribute to open source projects like [MLflow](https://github.com/mlflow/mlflow) and [AI Toolkit](https://github.com/ostris/ai-toolkit), where I wrote [`mlflow.diffusers`](https://github.com/mlflow/mlflow/tree/master/mlflow/diffusers), the MLflow flavor for tracking diffusion LoRA adapters. I went through 42 Paris. I spend a fair amount of time reading papers, browsing Hugging Face and testing new models, to understand how they work and what you can build with them. I especially like small models you can specialise for one task and run directly on the device, for lighter products that are kinder to privacy. Same idea with the infrastructure: my projects sit on servers I own and run, and training and model serving go through RunPod. And when I am not coding, I cook 🍳 ## Plocket β€” places worth remembering (iOS) https://getplocket.app Every place worth remembering. Plocket is an iOS app for the places you mean to go back to. One share in, one map out, and a way to hand a friend the good spots without handing over everything else. **One share. Every place in it.** Send Plocket a Maps link, an Instagram post, a message or a screenshot. It finds every place inside and puts them on your map. Four places in a post means four spots, not one lucky guess. You can also long-press the map when somewhere is already in front of you. **Make the map yours.** Every pin is somewhere you chose, saved for later or visited already. Filter by category to see what is close before the moment passes. Mark a place visited and keep the rating, photo and note that will bring it back. **Borrow taste you trust.** Step onto a friend's map and see the places they chose with the useful tip attached: what to order, when to go, how to skip the queue. There is no directory and nobody can look you up. A private, single-use invite only opens once you accept, and ratings and private notes never travel. ## Gourmand β€” iOS kitchen companion https://gourmand.app/ Your kitchen companion. Gourmand is an iOS recipe app I'm currently building β€” 500+ recipes, meal planning, nutrition tracking, cooking mode, auto-generated shopping lists, and every ingredient illustrated by hand. What's inside: - **Smart Recipes** β€” step-by-step instructions, nutrition info, and smart ingredient matching across 500+ dishes. - **Nutrition Tracking** β€” set daily calorie and macro targets with smart presets (weight loss, maintenance, etc.). - **Meal Planning** β€” drag recipes into your week, let the app generate the shopping list. - **Cooking Mode** β€” step-by-step view with timers, so the phone stays out of the way while you cook. - **Shopping Lists** β€” auto-built from your meal plan, organised by ingredient. A taste of what's cooking β€” a small sample from the 500+ recipe library, every dish ships with its own photo and step-by-step cooking mode: - [Cacio e Pepe](https://gourmand.app/recipes/ffa6a39f-bb83-43da-b039-a337b8cc081f) β€” 14 min Β· Easy - [Tatin de tomates](https://gourmand.app/recipes/ffdef530-5bea-4628-8561-cd780138c635) β€” 46 min Β· Easy - [Feta & tomates rΓ΄ties](https://gourmand.app/recipes/ff9dd1c0-1581-462d-a6ce-c2c95cf973ef) β€” 20 min Β· Easy - [Makis vΓ©gΓ©](https://gourmand.app/recipes/ff8c15a2-25eb-4579-9390-e8b818bac844) β€” 30 min Β· Easy **Design language.** Every ingredient ships with its own hand-illustrated sticker β€” no stock photos, just warm cream palette, friendly typography, and playful illustrated food everywhere. **Status.** Available on iOS, free to download. Bilingual β€” English and French. ## Open Source β€” mlflow Β· ostris/ai-toolkit Β· github/copilot-sdk Open source contributions to ML tooling. Two projects: [mlflow](https://github.com/mlflow/mlflow) β€” the experiment tracking platform β€” and [ostris/ai-toolkit](https://github.com/ostris/ai-toolkit), a popular diffusion model finetuning toolkit (10.5kβ˜…). **mlflow** β€” UI polish on the dataset drawer and image grid, plus a brand-new [`mlflow.diffusers`](https://github.com/mlflow/mlflow/tree/master/mlflow/diffusers) flavor for tracking diffusion LoRA adapters. - *Add mlflow.diffusers flavor for diffusion model LoRA adapters* β€” new first-party flavor letting users log, version, and serve LoRA adapters for diffusion models the same way they handle sklearn or pytorch models. - *Fix dataset details drawer* β€” local source display, profile parsing, broken link; three bugs in the dataset details UI fixed in one pass. - *Improve Image Grid chart UX for multi-run image comparison* β€” cleaner layout and interactions when comparing image artifacts across runs. - *feat(ui): add image comparison view for cross-run visual comparison* β€” dedicated view for diffing image artifacts between runs. **ostris/ai-toolkit** β€” Qwen-Image training fixes, plus feature work wiring up MLflow tracking and HuggingFace Hub checkpoint streaming. - *Add 1328 native resolution for Qwen Image training* β€” adds Qwen-Image's native 1328px bucket to the resolution presets. - *Fix Qwen attention mask crash with diffusers >=0.37* β€” restores Qwen-Image training after the diffusers 0.37 attention-mask API change. - *Add MLflow experiment tracking* β€” native MLflow integration: log hyperparams, losses, and samples directly into an MLflow tracking server. - *Push intermediate checkpoints to HuggingFace Hub* β€” stream checkpoints to HF Hub as training progresses, instead of only the final weights. **[github/copilot-sdk](https://github.com/github/copilot-sdk)** β€” codegen patch on the official GitHub Copilot SDK; every generated Python RPC method now takes a `timeout` kwarg forwarded straight to the JSON-RPC client. - *fix(python): add timeout parameter to generated RPC methods* β€” patches `scripts/codegen/python.ts` so every generated Python RPC method exposes an optional `timeout` kwarg forwarded to `JsonRpcClient.request()`, letting callers override the default 30s for long-running RPCs like `session.fleet.start`. **The through-line.** Two projects meet in the middle: ai-toolkit trains diffusion adapters, mlflow now has a flavor for them, and a PR teaches ai-toolkit to log its training runs straight into mlflow. copilot-sdk is the odd-one-out β€” a small codegen ergonomics fix on a Python client. ## Dispo β€” domain availability CLI (RDAP + WHOIS) https://github.com/Rasaboun/dispo Need to know if a domain is available? dispo is a TypeScript CLI that checks domain availability without paid APIs β€” RDAP first, WHOIS fallback when a TLD has no RDAP server. **Install.** One-shot via npx, or install globally. A standalone binary build is also published for macOS and Linux. Runs anywhere Node 18+ runs. No keys, no signup. ```sh npx @rasaboun/dispo --help npm install -g @rasaboun/dispo ``` **Usage.** Pass domains as args, pipe from stdin, or batch a file. Filter by TLD, tune concurrency and timeouts, or emit JSON for downstream tools. ```sh # single check dispo myapp.com # batch from file, only .dev TLD, JSON out dispo --tld .dev --json < ideas.txt # tune concurrency dispo --concurrency 20 --timeout 5000 a.com b.io c.dev ``` **Output.** Pretty table by default, JSON when you ask for it. Every result reports which protocol answered (rdap or whois) and how long the lookup took. Three states: registered, available, unknown. ``` domain status source time ────────────────────────────────────────────── myapp.com registered rdap 312 ms claude.ai registered rdap 287 ms foo.dev available whois 891 ms ``` Highlights: - RDAP first, WHOIS only when a TLD has no RDAP server - Configurable concurrency, timeout, and request delays - Batch input from args, stdin, or files - JSON output for piping into other tools - Standalone binaries (macOS ARM64/x64, Linux ARM64/x64) - Offline-tested with mocked network calls ## SeenFlow β€” visual testing for Maestro https://github.com/Rasaboun/SeenFlow Maestro taps by UI semantics β€” but some screens only exist as pixels. SeenFlow adds deterministic OCR visual selectors and action-effect assertions to Maestro flows. It is a compiler plus a local OCR sidecar β€” not a Maestro fork or a new device driver. Built with Bun + TypeScript + Python. **Example.** A native tap-and-assert pair becomes one declarative step: verify the effect isn't already on screen, find the text with OCR, tap, then poll fresh screenshots until the effect appears. If `Saved` is already visible before the tap, the flow fails before the action. ```yaml # native Maestro - tapOn: "Save" - assertVisible: "Saved" # seenflow - visionTap: text: "Save" expect: visibleText: "Saved" ``` **Pipeline.** Extended Maestro YAML compiles to standard Maestro YAML and runs through the official CLI, while a local PP-OCRv6 sidecar answers screenshot queries. Device interaction stays 100% Maestro. ONNX Runtime answers OCR in ~84ms median β€” ~3Γ— faster than the Paddle engine. ``` Extended Maestro YAML β†’ seenflow β†’ standard Maestro YAML β†’ official Maestro CLI β†˜ local PP-OCRv6 sidecar β†— ``` Highlights: - `visionTap` with exact / contains / fuzzy matching and confidence thresholds - Spatial selectors β€” `near`, `rightOf`, … with a 90Β° cone and `maxDistance` - Effect assertions on `tapOn`, `swipe`, `longPressOn` too β€” with a transition-safety precondition - Word-level geometry refined from merged OCR lines β€” never estimated from character widths - Distinct failure codes and per-step journals: screenshot, annotated image, OCR JSON - `--repeat --min-stability` measures flakiness across sequential runs ## Tools β€” eslint-plugin-no-relative-import https://github.com/Rasaboun/eslint-no-relative-import Tired of `../../../utils/helper`? eslint-plugin-no-relative-import rewrites relative imports into the path aliases declared in your nearest `tsconfig.json` β€” auto-fixable, monorepo-friendly, works with ESLint flat config, legacy config, and Oxlint. **Before / After.** Run `eslint --fix` once. Every relative import that matches a tsconfig path alias gets rewritten. Picks the most specific alias when multiple match. ```ts // Before import { helper } from "../../../utils/helper"; import { Button } from "../components/Button"; // After (auto-fix) import { helper } from "@/utils/helper"; import { Button } from "@/components/Button"; ``` **Install.** One devDependency, zero runtime impact. Works on Node 18+, ESLint 8.57+ or 9+. Plain npm install, no peer-dep gymnastics. ```sh npm install --save-dev eslint-plugin-no-relative-import ``` **ESLint flat config.** Drop it into your `eslint.config.js`. The recommended preset is also exported if you don't want to wire the rule yourself. Legacy `.eslintrc` and Oxlint `jsPlugins` also supported. ```js import noRelativeImport from "eslint-plugin-no-relative-import"; export default [ { plugins: { "no-relative-import": noRelativeImport }, rules: { "no-relative-import/no-relative-import": "error" }, }, ]; ``` **Granular control.** Keep co-located `./` imports, allowlist specific patterns, ignore assets, or provide manual aliases when no tsconfig is around. Every option supports the `*` wildcard. ```js "no-relative-import/no-relative-import": ["error", { alias: { "@/*": "./src/*" }, allowRelative: ["./styles.css", "../assets/*"], ignorePatterns: ["*.css", "*.graphql"], includeSiblingImports: false, }] ``` Highlights: - Auto-fixable β€” one `eslint --fix` converts the whole codebase - Reads `compilerOptions.paths` + `baseUrl`, follows `extends` chains - Monorepo-aware: each package resolves against its own tsconfig - Handles `import`, `export from`, dynamic `import()`, and `require()` - Works with ESLint flat config, legacy `.eslintrc`, and Oxlint `jsPlugins` - Manual aliases when there is no tsconfig at all ## Rasaboun-Connect β€” natural-language transit search https://rasaboun-connect.rasaboun.me/ Find the best way to get from one point to another in Île-de-France with this route planning tool. It takes into account public transportation, and walking! It takes into account real-time traffic conditions to offer you optimized routes. (An SNCF-Connect clone.) **Auto-completion.** Address autocomplete can help users quickly and easily find departure and arrival addresses, which can be helpful for users who are not familiar with the area. Type the start of your address and we will offer you the most relevant full addresses. **Itinerary list.** The itinerary list shows you all possible routes between two points. You can filter routes by mode of transport, duration, distance. Compare different routes to find the best one for you. **Itinerary detail.** Get detailed information on your itinerary, including step-by-step instructions and delays. ## AnimateQR β€” GIF / image QR codes https://animateqr.com Transform your images and GIFs into scannable QR codes with animateQR. **How it works.** Add an image, a URL and click on 'Get Your QR Code'. GIFs take more time. Works from a static image or from a GIF. ## Minishell β€” a simple shell in C https://github.com/Rasaboun/minishell A simple C shell that is perfect for users who want a simple, efficient shell written in C. A bash clone, built at 42 Paris. **Compilation and execution.** To compile, open a terminal and navigate to the root directory. Then run `make`. Then run `./minishell`. To quit, type ctrl-q. Features: - Displays the command history - Redirections (`>`, `>>`, `<`, `<<`) - Pipes (`|`) - Builtins (echo, cd, pwd, export, unset, env, exit) - Environment variable handling - Use `;` to join multiple commands ## Cub3D β€” 3D raycasting labyrinth https://github.com/Rasaboun/cub3d Are you ready to explore a unique 3D labyrinth? cub3d is a 3D raycasting game that lets you create your own labyrinth and explore it. Built at 42 Paris. **Configuration file.** The configuration file is a text file that allows players to modify game settings. It is located in the game's folder and can be opened with a text editor. You don't need to recompile the project every time you change the configuration file. **Compilation and execution.** To compile the game, open a terminal and navigate to the game's directory. Then run `make`. Then run `./Cub3d [directory of the .cub file]`.