Sanjay Santhanam
I build things end-to-end - backends, systems, ML, developer tools, native apps, browser games, and the occasional TUI. M.S. in Computer Science, Syracuse University.
Recent
Pinned projects
- optune — open-source Logitech Options+ replacement for macOS. Native Swift 6 + SwiftUI Liquid Glass, IOKit HID++ transport, 8 HID++ features (battery, DPI, SmartShift, button remap, host switching, onboard profiles, keyboard backlight, Fn-lock), per-app profiles, CLI + menu bar app + shared Core. Homebrew tap available.
- flight-sim — browser flight simulator with takeoff, landing, instrument HUD, and a Three.js terrain pipeline. No install, runs from
gh-pages. - snip — production-grade self-hosted URL shortener. TypeScript, Postgres, Redis, ClickHouse, BullMQ. Token-bucket rate limiting, signed webhooks, workspace RBAC, CLI client.
- tsk — keyboard-first markdown todo manager. Go, Bubbletea TUI, atomic writes, natural-language due dates, shell completions.
- core-stealth — privacy-auditing and QA browser harness. Tauri 2 + Rust core with a TypeScript UI, isolated browser profiles, fingerprint surface inspection, and region-locked QA runs.
- signalclaw — terminal-style quant research dashboard. TypeScript + Python backtest engine, ticker tape, equity and drawdown panes, regime-aware header, true-black palette.
- codeclone — code-clone detection and ML evaluation dashboard. TypeScript + Python, synced side-by-side diff, eval pass/fail grid, Dockerized services with Terraform config.
- clawhum — audio fingerprinting and hum-to-find search. Python DSP pipeline behind a TypeScript oscilloscope UI, waveform panels, transport meters, spectrogram match previews.
- adherence-ml — clinical ML observability for medication adherence models. TypeScript + Python, live KPI sparklines, SHAP waterfall explainer, IBM Plex type system.
- ai-particle-simulator — describe an effect, render 20K+ GPU-accelerated particles. React + Three.js + WebGL, LLM-driven prompt-to-shader pipeline.
CLIs & dev tools
- snippet-dev — local-first code snippet manager with fuzzy search, tags, syntax highlighting.
- markdown-zen — distraction-free markdown editor with focus mode and a custom in-browser parser.
- devdash — personal dev dashboard with glassmorphism UI, drag-and-drop widgets, Spotify and Gmail integrations.
- context-clipboard — context-aware clipboard for Chrome, Brave, Edge, and Firefox. MV3, local-only, captures source URL + page title + surrounding paragraph, in-page command palette, OCR.
- gitsight — open Git visualization for VS Code. Commit graph, blame heatmap, interactive rebase, GitHub PR review inline.
- clawreview — terse, dense, keyboard-first code review UI. Severity left-rails, mono everywhere, j/k nav, ⌘K palette.
- clawmind — paper-cream knowledge tool. Top composer, two-column reading, inline numbered citations.
- Med-Tracker — calm pharmacy app with day-rail timeline, capsule motifs, and warm pillbox tokens.
- regex-lab — live regex tester with shareable URL state.
- data-forge — CSV/JSON explorer with multi-column filters and canvas-rendered charts.
Visual & creative
- pixel-forge — image to retro pixel art. Floyd–Steinberg dithering, 14 palettes, SVG export.
- fractal-lab — Mandelbrot + Julia explorer with deep zoom and palette mapping.
- ascii-webcam — real-time webcam to ASCII in the browser.
- retro-terminal — CRT terminal emulator with scanlines and phosphor glow.
- CakePond — ambient SwiftUI koi pond for macOS.
- sunsprout — cozy pixel village + farm simulator that runs in the browser.
- gta-vibes — two browser games inspired by GTA. Top-down 2D and 3D Three.js, WASD, no install.
- shotclassify — broadcast-graphic screenshot classifier. Felt-green scorebug chips, ESPN-style ticker, live classification feed.
Open source contributions
Merged PRs across upstream projects.
AI, agents & memory
- openclaw/openclaw — agent runtime fixes for streamed-reply recovery (#71467), secrets auditing (#69581), Codex compaction auth (#86418), memory-core warning suppression (#69941), Discord voice session reuse (#97746), PluralKit DM pairing (#86397), omitted synthetic
maxTokensfallbacks (#98312), and clearer plugin-install failures (#98497). - HKUDS/LightRAG: #3406 exposes the thinking-token budget in role configuration.
- OpenAgentHQ/openagent-eval: #170 normalizes naive staleness timestamps in corpus evaluation; #192 includes the diagnosis step in structured error details.
- OpenAgentHQ/modeldock: #146 verifies that an Ollama model exists after a pull completes.
- bradygaster/squad: #1492 prevents binary corruption when files under
.squad/are externalized and restored. - MakazhanAlpamys/Soup: #315 runs built-in benchmark gate tasks during evaluation.
- turnstonelabs/turnstone: #862 records operator skill changes in session history.
- repowise-dev/repowise: #848 uses synchronous execution for webhook jobs.
- memtomem/memtomem: #1793 splits oversized Markdown parts during chunking.
- academy-agents/academy: #433 fixes the default Academy home-directory location.
- garrytan/gbrain: #1554 replaces a POSIX-only postinstall shim with a cross-platform Node implementation.
- laceyp99/conductor-core: #20 logs unsupported Google reasoning-effort values instead of silently accepting them.
- nesquena/hermes-webui — direct merges for an endless-scroll race (#1949), streaming timing (#1599), mobile keyboard Enter behavior (#3130), session-refresh polling (#3129), Docker guidance (#2950), provider-key errors (#2949), and transcript tool-card styling (#2948); release-integrated contributions for expired clarify prompts (#4524), bounded non-git context walks (#4225), paused cron grouping (#4223), default CLI-session visibility (#4222), external-session files (#3314), ephemeral turn fields (#3313, #3131), remote gateway health (#3312), SSE connection handling (#3128), intermediate-message navigation (#3127), model-picker keyboard navigation (#2952), cross-container liveness (#1887), provider configuration (#1883, #1783), and streaming scroll unpinning (#1732).
- outsourc-e/hermes-workspace — slash-menu autocomplete (#251), a distinct gateway-auth-rejected path (#250), and a dashboard health probe integrated through a shared commit (#289).
- MrReasonable/sluice: the empty Claude Max response guard from #33 landed through replacement PR #37.
- steipete/CodexBar: the missing
five_hourOAuth fallback from #741 was folded into a maintainer patch onmain. - huggingface/huggingface_hub — #4278: fix typos in comments and a debug log message.
- OpenHands/software-agent-sdk — #3399: pin ACP
npxlaunchers to reviewed versions. - OpenHands/OpenHands — #14577: fix typos across comments, docstrings, and log messages.
- plastic-labs/honcho — corrected the surprisal filter format for level observations (#581).
- dkedar7/streamlit-mcp — #63 accepts typed current values in schemas for widgets with non-string options.
Language tooling & lexers
- astral-sh/ruff — #26318: skip
D418(overload-with-docstring) in stub files, where overloads cannot carry the docstring on an implementation. - pygments/pygments: 15 lexer and formatter fixes across Kotlin (#3178, #3212), C++ (#3176), LaTeX/TeX (#3175, #3204), TypeScript (#3172), Ruby (#3171), Vala (#3206, #3207), Jsonnet (#3208), YAML (#3209), SCSS (#3210), Kusto (#3211), C# (#3213), and JSX (#3214).
- gilch/hissp: #327 falls back to a higher pickle protocol when protocol 0 fails.
- davidhalter/parso: #242 stops treating a walrus argument as a keyword argument.
- trentm/python-markdown2: #719 treats
headandstyleas block-level tags. - PyCQA/docformatter: #364 stops treating a bracketed string literal as an attribute docstring; #363 stops splitting a summary on a period inside an inline literal; #362 stops emitting stray newline tokens before a trailing comment.
- PyCQA/autoflake: #361 treats interpreter builtin modules as safe imports.
- tconbeer/sqlfmt: #843 stops treating semicolons inside comments as statement terminators.
- pylint-dev/pylint: #11187 fixes an
assignment-from-no-returnfalse positive on a trailing raise. - pylint-dev/astroid: #3152 only adds the
_HAS_DEFAULT_FACTORYsentinel when adefault_factoryis used.
Developer & infra tooling
- codespell-project/codespell: #3975 scopes TOML configuration reads to
[tool.codespell]. - fsspec/filesystem_spec: #2072 fixes S3 parent paths in
ArrowFSWrapper; #2074 fixes removal of directory symlinks inLocalFileSystem. - shanevcantwell/llauncher: #353 keeps same-model servers distinct by port in the UI.
- mila-iqia/cluv: #144 preserves an existing results directory during initialization.
- ministackorg/ministack: #1089 honors
LogTypewhen returning Lambda invocation logs. - wntrblm/nox: #1127 corrects
python_versions()minimum resolution for major-only and multiple lower bounds. - urwid/urwid: #1187 copies signal-handler lists before emission so mutation cannot skip callbacks.
- BrianPugh/cyclopts: #860 restores zsh subcommand completion after meta positionals.
- tomerfiliba/plumbum: #838 ignores annotations for non-positional
mainparameters in the CLI layer. - rclone/rclone — goroutine leak in
NewStatsGroupfor zero-transfer rc jobs (#9568);serve webdavdefaultOverwrite: Tfor COPY/MOVE (#9558). - goreleaser/goreleaser — #6684: default the winget head branch to a versioned template.
- astral-sh/uv — #19983: explain why files are skipped during registry index parsing.
- helix-editor/helix — #15939: editorconfig test coverage for empty alternate brace groups.
- prowler-cloud/prowler — #11823: skip
MANUALfindings in the compliance section tally to avoid aKeyError. - 1Panel-dev/1Panel — IPv6 hosts in the self-signed SSL flow (#12652) and
exec.LookPathfor cross-platform command detection (#12651). - sqlfluff/sqlfluff: #8062 parses ClickHouse tuple-element access on arbitrary expressions.
- yfosp/start-here: #953 adds Sanjay to the contributor list.
- napalm-automation/napalm: #2333 brackets literal IPv6 hosts when building the NX-API URL.
- Ericsson/codechecker: #5002 strips ANSI escapes from clang-tidy output when collecting mentioned files.
- soxoj/maigret: #2924 stops the
SUPPORTED_IDSbranch re-adding a rejected username inextract_ids_from_page. - sartography/SpiffWorkflow: #483 raises a clear
ValidationExceptionfor aServiceTaskwith no operator. - casperdcl/git-fame: #125 counts LOC and files when passing multiple repos.
- tqdm/shtab: #221 treats
nargs=0custom actions as flags in zsh; #220 supports non-sequence choices in zsh completion. - nicolargo/glances: #3635 resolves port alert level by severity instead of dict ordering; #3626 corrects the column/value mismatch for list plugins in TimescaleDB.
- boxed/mutmut: #542 forwards the generator return value through the trampoline.
- mkb79/audible-cli: #269 passes the config path to
click.editas a string. - ipspace/netlab: #3720 catches
KeyboardInterruptwhen aborting test cleanup. - MarketSquare/robotframework-robocop: #1786 marks
--ignorevalues as matched for rules below--threshold. - GothenburgBitFactory/bugwarrior: #1227 coerces the Logseq block id to an int for a stable unique key.
- opensteno/plover: #1857 escapes characters outside code page 1252 on RTF/CRE export.
- amanusk/s-tui: #296 handles non-
IndexErrorfailures in graph and summary updates; #295 falls back to/proc/device-tree/modelfor the processor name. - abrignoni/iLEAPP: #1773 skips
NoteStore.sqlitefiles without the CloudKit table; #1772 handles alarms whose sound is a song. - sipyourdrink-ltd/bernstein: #3163 fails loudly when no trend-scan fetcher is configured.
- microsoft/WinAppVSCE: #116 resolves a relative
launch.jsonworkingDirectoryagainst the workspace folder. - GNS3/gns3-server: #2833 stops starting nodes when deleting a project; #2831 corrects an always-true state check in
DockerVM.stop(). - Kohei-Wada/taskdog: #1168 reports real statistics sections in
get_statistics; #1165 aligns the SQLend_datefilter with whole-day semantics. - doorstop-dev/doorstop: #808 stops escaping dollar signs that delimit inline math in LaTeX export; #802 reports links to inactive items as inactive rather than unknown.
- ebroecker/canmatrix: #919 preserves the
NS_new-symbols section on dbc-to-dbc conversion. - mnemosyne-oss/mnemosyne: #542 reports
memory_not_foundwhen invalidate matches no row. - rmartin16/qbittorrent-api: #644 preserves the cached client when slicing or copying
Listobjects. - ai-dynamo/aiperf: #1195 handles top-level JSON array responses.
- Bachmann1234/diff_cover: #612 honors the
formatoption from the config file. - CodeGraphContext/CodeGraphContext: #1376 wires
PARALLEL_WORKERSconfig to indexing concurrency. - mstar-project/mstar: #190 decodes streamed lines when
Content-Typehas no charset. - carderne/signal-export: #224 stops creating the output folder when no chats are exported.
- snstac/pytak: #104 warns when WS TX sends raw XML to a TAK Protocol endpoint.
- archlinux/archinstall: #4670 adds ghostscript to the print service packages.
- apache/libcloud: #2173 includes IPv6 addresses in DigitalOcean node public/private IPs.
- common-workflow-language/cwltool: #2316 gives a meaningful error for an empty job order file.
- jorio/gitfourchette: #130 reports Git's error instead of
NotImplementedErroron cherry-pick. - papis/papis: #1212 makes YAML export appendable.
Python libraries
- chardet/chardet: #372 stops ASCII
+<digits>text from being misdetected as UTF-7. - uqfoundation/dill: #764 marks
TestNamespaceas a non-test class during collection. - mahmoud/boltons: #418 prevents
singularize()from mangling words ending inss. - redis/redis-py: #4193 restores Sentinel connection-pool capacity after failover.
- pydantic/pydantic-settings: #910 parses enum names through nested annotations.
- pydantic/pydantic-extra-types: #403 rejects non-ASCII digits in ABA routing numbers.
- jd/tenacity: #654 avoids unnecessary exponential-wait computation.
- GrahamDumpleton/wrapt: #345 makes
bytes()on a proxy match the wrapped object. - splintered-reality/py_trees: #505 recovers memory sequences after child replacement.
- nose-devs/nose2: #674 fixes JUnit XML timestamps for subtests.
- python-poetry/tomlkit: #551 preserves a multiline string's leading newline when built with
string(). - rthalley/dnspython — #1279: raise
BadTTLfor non-decimal Unicode digits indns.ttl.from_text(). - lepture/mistune — #462: escape literal emphasis markers in
MarkdownRenderer; #471: apply the escape flag to a user-supplied HTML renderer. - wireservice/agate — #813: fix
Table.from_fixedreading data as schema for a file-likeschema_path. - kvesteri/sqlalchemy-utils — #812: fix
PasswordTypedropping updates when the column was previously NULL. - neuml/txtai — #1125: raise
SQLErroron unterminated bracket and function clauses. - dottxt-ai/outlines — #1898: don't require a provider's optional SDK to normalize errors.
- marshmallow-code/webargs — #1076: modernize the aiohttpparser docstring example.
- vimalloc/flask-jwt-extended — #579: replace deprecated
datetime.utcnow(). - tweepy/tweepy — #2241: replace deprecated
datetime.utcnow()inMongodbCache.store. - wolph/python-progressbar — #318: detect color support for
xterm-*TERM values. - jab/bidict: #380 materializes
product()inputs passed to parametrized tests. - fabiocaccamo/python-benedict: #583 handles non-string dictionary keys that contain lists in key-list and key-path traversal.
- more-itertools/more-itertools: #1200 rejects negative slice sizes in
sliced(). - Yakifo/amqtt — #350 treats empty or truncated MQTT fixed-header reads as end-of-stream.
- aplbrain/grand-cypher: #114 returns NULL from scalar functions given invalid argument types.
- sooperset/mcp-atlassian: #1550 surfaces the environment system field on
JiraIssue. - mpmath/mpmath: #1150 avoids spurious overflow in
fp.gammaprod. - deeplook/svglib: #499 respects the
visibilityproperty on shapes; #494 looks up unquoted font-family names containing spaces; #493 respectsdisplay:noneset via thestyleattribute. - PyThaiNLP/pythainlp: #1473 romanizes royin words containing ฤ.
- optiland/optiland: #702 adds descriptive messages to bare
ValueErrorraises in paraxial. - astropy/astropy: #20174 writes
solRadandsolLuminstead ofRsunandLsunin the CDS format. - guessit-io/guessit: #942 keeps the title when
alternative_titleis excluded; #936 keeps a leading country word that opens the title. - MechanicalSoup/MechanicalSoup: #484 detects HTML from raw leading bytes in
__looks_like_html; #483 raises an explanatory error fromlinks()when no page is loaded. - gorakhargosh/watchdog: #1183 stops
PermissionErrorkilling the kqueue emitter thread on BSD. - anymail/django-anymail: #479 reports an unsupported feature for
merge_datawithouttemplate_id. - pyathena-dev/PyAthena: #743 returns the formatted DATE literal from
AthenaDate.process. - dynaconf/dynaconf: #1435 cleans up nested
dynaconf_mergetokens when the parent key is new; #1434 keeps sibling keys that share a dotted-path leaf name. - invoice-x/invoice2data: #716 emits a single CSV header row across all invoices.
- Ad-meliorael/percentify: #35 keeps small p-values from rounding to zero in
correlate. - marcosschroh/dataclasses-avroschema: #964 serializes records without fields to avro-json; #963 stops mutating
Meta.field_orderduring schema generation.
Web, media & apps
- alphacrack/readme2demo: #134 gives the step tutorial a distinct SEO title.
- mantinedev/mantine: mark non-
menuitemchildren insideMenu.Dropdownas presentational for WAI-ARIA 1.2 compliance (#9004); export theFormProviderPropstype (#9009). - suitenumerique/meet — standardized role terminology across localizations (#1285).
- Stremio/stremio-web — Lithuanian ISO 639-2 language code fix (#1230).
- NuvioMedia/NuvioTV — restored the Android TV keyboard
Nextaction (#1453) and added a subtitle-delay reset shortcut (#1452). - Flexget/Flexget — recursive
exists_seriessupport for nested season folders (#4987) and video-only matching that skips subtitles and metadata (#4986). - PaRaN01a-hash/ultra-max-addon: #15 adds manifest behavior hints and ID prefixes for Nuvio compatibility.
- aliasvault/aliasvault: #1893 adds HTML, plain-text, and source views for email content.
- plotly/dash: #3936 uses the proxied URL as the Jupyter server URL.
- posit-dev/great-docs: #299 preserves source order for sidebar subsections.
- Donkie/Spoolman: #987 strips the leading
#from filament color codes. - reflex-dev/xy: #389 floors the log axis lower bound when an explicit margin is set.
- wkentaro/labelme: #2425 degrades to stderr-only logging when the log file fails; #2417 reports the decode allocation limit instead of "Allowed formats".
- GoogleChrome/chromium-dashboard: #6656 rejects milestone zero in
ChannelsAPI. - jacebrowning/memegen: #1046 only drops trailing blank lines when cleaning URLs.
Stack
Swift · Go · TypeScript · Python · Rust · Node · Postgres · Redis · ClickHouse · Docker · GCP · AWS · React · Three.js · PyTorch · TensorFlow · macOS / IOKit / SwiftUI
Selected publications
- Drowsiness Detection with OpenCV — IEEE ICESC 2021. 10.1109/ICESC51422.2021.9532758 · code
- Animal Detection for Road Safety using Deep Learning — IEEE ICCICA 2021. 10.1109/ICCICA52458.2021.9697287
- Model Proposal for a YOLO Object Detection Algorithm based Social Distancing Detection System — IEEE ICCICA 2021. 10.1109/ICCICA52458.2021.9697212
- Computer Vision based Road Lane Detection — Artificial & Computational Intelligence, 2021.
- Recognition of Pneumonia from X-Ray Image Patterns using Convolutional Neural Networks — 2021. code
Research
Contact
- Email — sanjays2402@gmail.com
- LinkedIn — linkedin.com/in/sanjay24
Pinned Loading
-
Convolutional neural network that classifies pneumonia from chest X-rays. Trained on the Kaggle Chest X-Ray Pneumonia dataset with TensorFlow.
Python
-
Real-time driver drowsiness detection using OpenCV and the Eye Aspect Ratio (EAR) algorithm. MediaPipe-backed facial landmark pipeline with configurable thresholds and audible alerts. Published in …
Python
-
Real-time road lane detection pipeline built with OpenCV. Implements color masking, region-of-interest extraction, Canny edge detection, and Hough line transforms with averaged lane overlay.
Jupyter Notebook